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

How to produce a True UUID in Java?

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

A UUID is 128 bits long, and can guarantee uniqueness across space and time.

看起来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 中有没有办法做到这一点?

因为你的熵受限于你的记忆,你永远无法确保 UUID 是 "guaranteed, true, globally unique result"。不过99.99999999999%已经很不错了

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

可能会出现重复,但 IIRC,其中一部分是根据您当前的时间创建的,因此如果您只是每 5 分钟创建一个,您应该是安全的。

UUID 的生成方法有多种。您正在使用的类型完全按照它应该的方式运行。您正在使用 nameUUIDFromBytes、"Static factory to retrieve a type 3 (name based) UUID based on the specified byte array."

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

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

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

相比之下,类型 3 或类型 5 UUID 的唯一性取决于您输入的内容。

A 类型 1 UUID(基于时间的)在某些限制条件下应该非常 "more" 唯一。 Java 平台不支持生成 type-1 UUID,但我编写了代码(可能未发布)以通过 JNI 调用 UUID 生成库。是18行C和11行Java.