如何在Java中生成真正的UUID?

我的印象是,UUID规范要求保证的,真实的,全球唯一的结果,不是唯一的99.99999999999%的时间,而是100%的时间。 从规格:

UUID的长度为128位,可以保证空间和时间的唯一性。

它看起来像Java只支持UUID规范的V3和V4。 V4并不是真正独特的。 使用nameUUIDFromBytes进行V3实现时,由于计算机速度太快(编辑:循环到10并调用new Date().getTime()会产生重复项,因为计算机循环比new Date().getTime()new Date().getTime()可以在每次迭代时产生不同的值):

String seed;
for (int i = 0; i < 10; i++) {
     seed = "<hostname>" + new Date().getTime();
    System.out.println(java.util.UUID.nameUUIDFromBytes(seed.getBytes()));
}

我错误地认为UUID是100%独特的,而且它仅仅是独特的,但不完全如此? 无论如何要在Java中做到这一点?


UUID生成有不同的方法。 你使用的那种行为完全如其应该的那样。 您正在使用nameUUIDFromBytes ,“静态工厂根据指定的字节数组检索类型3(基于名称)的UUID。”

如果给定相同的名称,这将生成相同的UUID。 正如你发现的,你的循环每次都传入相同的名字,所以你得到相同的UUID。

在这里看看Gabe的建议:使用哪个UUID版本? 他建议你使用V4,正如其他人指出的那样,对于任何现实的用例来说都足够好。


因为你的熵仅限于你的记忆,你永远不能确保UUID是“保证的,真实的,全球唯一的结果”。 不过,99.99999999999%已经很不错了。

如果你想确保你的数据库中有唯一的值,你可以使用一个简单的整数来增加它的唯一性。 如果你想使用UUID并且确定它们是唯一的,你只需要在创建时检查它。 如果有重复,只需创建另一个,直到它是唯一的。

重复可能发生,但是IIRC,其中一部分是根据您当前的时间创建的,所以如果您每5分钟创建一个,则应该是安全的。


正如其他人指出的那样,由UUID.randomUUID()返回的类型UUID.randomUUID()对于任何实际应用都可能是足够独特的。 不是很可能是病态的情况:例如,将VM回滚到实时快照,而不重新启动Java进程,以便随机数生成器返回到确切的先前状态。

相比之下,类型3或类型5 UUID只与您输入的内容相同。

类型1的UUID(基于时间的)应该在一定的限制下稍微“更”独特。 Java平台不包括对生成1类UUID的支持,但我编写了代码(可能未发布)通过JNI调用生成UUID库。 它有18行C和11行Java。

链接地址: http://www.djcxy.com/p/91489.html

上一篇: How to produce a True UUID in Java?

下一篇: Is it possible to generate duplicate UUIDs in the same millisecond?