繁体   English   中英

UUID.randomUUID() 与 SecureRandom

[英]UUID.randomUUID() vs SecureRandom

我试图了解使用 UUID.randomUUID() 而不是 SecureRandom 生成器的优势,因为前者在内部使用 securerandom。

好吧, 源代码显示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 生成器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM