如何在Java中生成True UUID?

时间:2015-03-25 20:52:47

标签: java uuid

我的印象是,UUID规范需要一个有保证的,真实的,全球唯一的结果,而不是99.99999999999%的独特时间,但真正100%的时间。来自spec

  

UUID长128位,可以保证      空间和时间的独特性。

看起来java只支持UUID规范的V3和V4。 V4并不是真正独一无二的。使用nameUUIDFromBytes的V3实现,以下结果是重复的,因为计算机太快(编辑:循环到10并且调用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中这样做?

3 个答案:

答案 0 :(得分:4)

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

如果给出相同的名称,则生成相同的UUID。正如您所发现的,您的循环每次都传递相同的名称,因此您获得相同的UUID。

在这里查看Gabe的建议:Which UUID version to use? 他建议你使用V4,正如其他人指出的那样,V4足以应付任何真实的用例。

答案 1 :(得分:2)

因为您的熵仅限于您的记忆,所以您永远无法确保UUID是“保证,真实,全球唯一的结果”。但是,99.99999999999%已经相当不错了。

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

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

答案 2 :(得分:0)

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

相比之下,type-3或type-5 UUID只与你投入的UUID一样独特。

类型1 UUID(基于时间)应该非常轻微&#34;更多&#34;独特的,在某些限制下。 Java平台不包括对生成类型1 UUID的支持,但是我编写了代码(可能未发布)以通过JNI调用UUID生成库。这是18行C和11行Java。