簡體   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