我知道随机uuid在理论上有非常非常非常低的碰撞概率,但我想知道,在实践中,Java的randomUUID()在没有碰撞方面有多好?有人有经验可以分享吗?


当前回答

许多答案都讨论了需要生成多少uuid才能达到50%的碰撞几率。但是50%、25%甚至1%的碰撞概率对于一个必须(实际上)不可能发生碰撞的应用程序来说是毫无价值的。

程序员是否经常将其他可能发生的事件视为“不可能”?

当我们将数据写入磁盘或内存并再次读取时,我们想当然地认为数据是正确的。我们依靠设备的纠错功能来检测任何损坏。但是,未检测到错误的几率实际上在2-50左右。

对随机uuid应用类似的标准不是很有意义吗?如果您这样做,您将发现在大约1000亿个随机uuid(236.5)的集合中,“不可能”的碰撞是可能的。

这是一个天文数字,但像国家医疗保健系统中的逐项计费,或在大量设备上记录高频传感器数据等应用程序肯定会遇到这些限制。如果你正在写下一篇《银河系漫游指南》,不要试图为每篇文章分配uuid !

其他回答

UUID的原始生成方案是将UUID版本与生成UUID的计算机的MAC地址以及自西方采用格里高利历法以来的100纳秒间隔数连接起来。通过表示空间(计算机)和时间(间隔数)中的单个点,值碰撞的机会实际上为零。

UUID使用java.security。SecureRandom,它被认为是“加密强的”。虽然没有指定实际的实现,并且在不同的JVM之间可能有所不同(这意味着所做的任何具体语句只对一个特定的JVM有效),但它确实要求输出必须通过统计随机数生成器测试。

实现中总是可能包含破坏这一切的细微错误(参见OpenSSH密钥生成错误),但我不认为有任何具体理由担心Java uuid的随机性。

维基百科给出了一个很好的答案 http://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions

the number of random version 4 UUIDs which need to be generated in order to have a 50% probability of at least one collision is 2.71 quintillion, computed as follows: ... This number is equivalent to generating 1 billion UUIDs per second for about 85 years, and a file containing this many UUIDs, at 16 bytes per UUID, would be about 45 exabytes, many times larger than the largest databases currently in existence, which are on the order of hundreds of petabytes. ... Thus, for there to be a one in a billion chance of duplication, 103 trillion version 4 UUIDs must be generated.

我们已经在我们的应用程序中使用Java的随机UUID一年多了,而且使用得非常广泛。但是我们从来没有遇到过碰撞。

我去年买彩票,但我从来没有中过.... 但似乎彩票中了奖…

Doc: https://www.rfc-editor.org/rfc/rfc4122

类型1:未实现。如果uuid在同一时刻生成,则可能发生冲突。Impl可以人为地实现a同步,以绕过这个问题。

类型2:从未看到实现。

类型3:md5哈希:可能发生冲突(128位-2技术字节)

类型4:随机:可能发生碰撞(如抽签)。注意jdk6 impl没有使用一个“真正的”安全随机,因为PRNG算法不是由开发人员选择的,你可以强制系统使用一个“糟糕的”PRNG算法。所以UUID是可预测的。

类型5:sha1哈希:未实现:可能发生冲突(160位-2技术字节)