我试图了解使用 UUID.randomUUID() 优于 SecureRandom 生成器的优势,因为前者在内部使用securerandom。
4 回答
好吧,源代码显示UUID.randomUUID
使用SecureRandom
.
public static UUID [More ...] randomUUID() {
SecureRandom ng = numberGenerator;
if (ng == null) {
numberGenerator = ng = new SecureRandom();
}
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new UUID(randomBytes);
}
如您所见,您可以使用其中任何一种,但在安全的 UUID 中,您有 6 个非随机位,如果您很挑剔,这可能会被视为劣势。
随机数有随机重复的机会。随机性越低(除非有一些协调),产生相同数字两次的机会就越大。
https://en.wikipedia.org/wiki/Birthday_problem
随着您生成更多随机数,相同数字重复的机会会增加,因为每个 id 必须与其他每个 id 不同。
SecureRandom 允许你选择你想要多少位的随机性。让它太小,它们很有可能会被重复。您可以在几分之一秒内获得重复的随机 32 位 id。
UUID 将标准设置为 128 位(或者正如 uoyilmaz 指出的那样,122 位是随机的)这对于大多数用例来说已经足够了。但是,如果您想要一个随机字符串,我会很想使用比 16 更多的位和/或更高的基数。例如 Java 支持基数 36 和 64,这意味着您可以有更短的 id,或者相同长度的 ID 具有更多随机性。
注意:UUID 格式-
在它的转储中有多个,虽然我没有看到它们的值,它们只是使字符串更长。
感谢您提供的所有技术答案。我自己也对导致我来到这里的两者之间的差异感到困惑。但是后来,我突然想到:如果你只调用一次函数,那么没有区别,因为这两种方法都会生成一个无法预先计算的数字。但是如果多次调用该函数,那么它们在这里会有所不同,因为统计正态分布是随机数生成器的属性,而这不是 UUID 的属性。UUID 力求唯一性,实际上它使用您计算机的 MAC 硬件地址、当前纪元秒数等推导出提供的数字。最终,如果您循环调用 UUID 值,它将不会在统计上呈正态分布。
UUID 不是一个随机数:它是一个通用的唯一 ID。您可以确定没有人可以生成相同的十六进制字符串。
随机数是另一回事:它不是十六进制字符串,也不是普遍唯一的。
这个库提供了一个更有效和更完整的 UUID 生成器。