我知道理论上随机生成的UUID具有非常非常低的碰撞概率,但我想知道,在实践中,Java的randomUUID()
在避免碰撞方面有多好?有人有任何经验分享吗?
我知道理论上随机生成的UUID具有非常非常低的碰撞概率,但我想知道,在实践中,Java的randomUUID()
在避免碰撞方面有多好?有人有任何经验分享吗?
UUID使用java.security.SecureRandom
,这是一个“密码学强”的算法。虽然实际的实现方式没有明确规定,并且可能因为不同JVM而有所差异(这意味着任何具体的描述仅适用于特定的JVM),但它必须通过统计随机数生成器测试。
虽然实现过程中可能存在微妙的错误(参见OpenSSH密钥生成漏洞),但我认为没有具体的理由担心Java UUID的随机性。
维基百科给出了一个很好的答案 http://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions
生成随机版本4 UUID的数量,以至少有50%的概率发生至少一次冲突,需要生成2.71万亿个,计算如下:
...
这个数字相当于每秒生成10亿个UUID约85年,一个包含这么多UUID的文件,每个UUID是16字节,将达到45艾字节,比目前已经存在的最大数据库大得多,后者大约是数百拍字节的规模。
...
因此,要使重复的概率达到十亿分之一,必须生成103万亿个版本4 UUID。
UUID.randomUUID()
生成的随机性质量,而不是关于给定完美随机数生成器的理论概率。 - kratenko虽然我不是专家,但我认为足够聪明的人们多年来一直在研究Java的随机数生成器。因此,我也认为随机UUID很好。因此,您应该真正具有理论上的冲突概率(对于所有可能的UUID来说,这大约是1:3×10^38)。有人知道仅针对随机UUID,这会如何改变吗?是上面的1/(16×4)
吗?
从我的实际经验来看,我到目前为止从未见过任何碰撞。当我第一次遇到碰撞时,我可能会长出惊人的长胡须;)
在以前的雇主那里,我们有一个包含随机 uuid 的独特列。它刚上线一周后就出现了重复。当然,概率很低,但并非为零。这就是为什么 Log4j 2 包含 UuidUtil.getTimeBasedUuid。只要您不在单个服务器上每毫秒生成超过10,000个 UUID,它就会生成一个可持续8,925年的唯一UUID。
UUID的原始生成方案是将UUID版本与生成UUID的计算机的MAC地址以及自公历在西方的采用以来的100纳秒间隔数连接起来。通过表示空间(计算机)和时间(间隔数)中的单个点,值冲突的可能性有效地为零。
去年我参加了彩票,但我从未赢过......但似乎这里有中奖者......
文档:https://www.rfc-editor.org/rfc/rfc4122
类型1:未实现。如果在同一时刻生成UUID,则可能发生冲突。可以通过人为异步实现来规避此问题。
类型2:从未见过实现。
类型3:MD5哈希:可能会发生冲突(128位-2个技术字节)
类型4:随机数:可能会发生冲突(就像彩票一样)。请注意,jdk6实现不使用“真正的”安全随机数,因为PRNG算法不是由开发人员选择的,您可以强制系统使用“差劲”的PRNG算法。因此,您的UUID是可预测的。
类型5:SHA1哈希:未实现:可能会发生冲突(160位-2个技术字节)
我们在应用程序中已经使用Java的随机UUID超过一年,而且使用非常广泛。但是我们从未遇到过碰撞的情况。