開發者工具 · UUID 產生器
v4 UUID 有幾個隨機位元? 122,不是 128
· 工作原理
uuid 密碼學 瀏覽器 API
隨機 UUID 中的 6 個 128 位元由標準固定,留下 122 用於隨機性。這篇文章展示如何誠實地估計碰撞幾率,以及為什麼真正的碰撞來自損壞的發電機,而不是數學。
建築師的問題:我們會得到複製品嗎? — 擔憂從何而來以及為什麼答案取決於產生器
架構師問:如果我們在十年內每天產生 10 萬個 UUID,我們會得到重複的嗎?誠實的答案是:如果產生器在密碼學上是安全的,那麼幾乎肯定不會;如果發電機壞了,幾乎可以肯定是的。 RFC 9562 數學是合理的:具有 122 隨機位元的 v4 UUID 的衝突機率大約是 n² / 2 的 123 次方,其中 n 是產生的識別符的數量。對於大多數實際系統,這種機率可以忽略不計。問題是這個公式假設每一位都是真正隨機的。如果產生器洩漏或重複或可預見地播種,則公式是錯誤的,重複將不可避免。 128 位元佈局包含四個版本位元(0100 對於 v4)和兩個變體位元(10 對於 RFC 9562),它們是由標準固定和設定的。
表示哪六個位元 - 四個版本位和兩個變體位,以及為什麼它們是設定的而不是隨機的
剩下 122 位元用於隨機性。這個公式有時稱為 2 到 122 個隨機位,產生唯一的值。使用生日悖論近似,n 個隨機產生的值之間至少發生一次衝突的機率大約是 n²/2 的 123 次。對於 n = 100 萬,則為 (10^6)² / 2^123 = 10^12 / 9。3 × 10^36,大約為 10^-25。對於 n = 100 億,仍然約為 10^-16。這些並不是「實際上為零」;他們是「你永遠不會觀察到這一點。」生日近似值給出了計算風險的具體方法:計算你計劃產生的 UUID,對該數字進行平方,然後除以 2 的 123 次方。如果產生器是瀏覽器的 crypto.getRandomValues,則每一位都由作業系統熵支援。如果是數學的話。
簡單來說,生日近似值 — n 個標識符之間至少發生一次衝突的機率大約是 n 平方除以 2 得到 123
對於由不合適或重複狀態產生器產生的 UUID,數學模型會崩潰,因為其獨立性假設是錯誤的。固定的測試種子、複製的夾具或過程快照可以重播值,即使文字仍然帶有版本 4 半位元組。這些是實現缺陷,而不是 122 欄位計算錯誤的證據。另一個常見的來源是將相同的文字標識符複製到多個裝置中,然後合併它們的資料。調查重複項時,請保留產生器、種子策略、流程生命週期和匯入歷史記錄。不要從一個重複值跳到聲稱獨立 CSPRNG 輸出耗盡了 UUID 空間。
工作範例 - 將規定的發電率和時間跨度插入近似值,顯示每個步驟,以便您可以替換自己的數字
沒有隨機狀態重新同步的進程分叉。使用 Math.random 而不是 crypto.getRandomValues 的錯誤。手工製作的測試夾具,在多行中使用相同的 UUID,並在生產中意外使用。舊版的 UUID 庫存在範圍限製或狀態錯誤。這些場景都不涉及生日近似數學;它們涉及實施失敗或操作錯誤。誠實地計算系統的衝突風險:計算 UUID 產生率(每秒、每天、每年),將其投影到系統執行的時間內,並將總數代入生日公式。如果您的系統在五年內每天產生 100,000 個 UUID(總共 1.82 億個),則衝突機率為 (1. 82 × 10^8)² / 2^123 ≈ 3. 3 × 10^-22,可以忽略不計。
重複項實際上來自哪裡 - Math.random 種子、克隆虛擬機器、具有複製狀態的分叉進程以及在固定裝置中複製貼上
如果一年每秒產生 1000 萬個(總計 315 兆),則機率為 (3. 15 × 10^14)² / 2^123 ≈ 10^-10,這仍然是微乎其微的小。這些估計假設每一位都是獨立且隨機的。 ToolAcre 產生器使用 crypto.getRandomValues,它為您提供 CSPRNG 支援的隨機性;操作是您唯一需要信任的部分。切勿以碰撞機率為藉口來跳過適當的授權檢查。 UUID 不是密碼,不是存取令牌,也不是秘密,即使它是 122 個隨機位元。獨特性就是好處;不可預測性是一個單獨的(也是更重要的)屬性,可以防止猜測。生日數學處理唯一性;它不涉及生命週期(這個 UUID 應該過期嗎?)、保密(在存儲之前是否需要對其進行哈希處理?)或授權(擁有這個 UUID 是否可以證明有關調用者的任何信息?)。 ToolAcre 產生器為您提供具有 122 個隨機位元的 CSPRNG 支援的 UUID,這意味著數學的唯一性成立並不可預測性是合理的。其他一切(令牌驗證、到期、存取控制)都是您的應用程式的責任。機率公式假設每個產生的 UUID 與前幾代無關。如果您的系統從單一 CSPRNG 實例產生標識符,並每次呼叫都從作業系統中獲取新的隨機性,則獨立性假設成立。如果您的系統使用已快取的 CSPRNG 狀態或沒有作業系統重新播種的種子產生器,則該假設將不成立。如果熵源耗盡(發生在某些嵌入式系統或負載下的虛擬機器上),或者如果進程之間從未重置隨機狀態(進程分叉而不重新播種 CSPRNG),則衝突風險會急劇增加。
這不包括 - v1 和 v7 的唯一性,它依賴於時間戳記和時鐘序列,而不僅僅是隨機性
ToolAcre 回退為每個位元組數組呼叫 crypto.getRandomValues,並不保存應用程式級 PRNG 狀態。平台內部仍由瀏覽器和作業系統負責。模擬與真實發電機的碰撞顯示了理論與實踐之間的差異。從相同種子開始使用 Math.random 構建的產生器將產生相同的序列;您將在幾百到幾千個產生值內看到第一次 UUID 衝突,而不是像生日近似預測的那樣在 2^60 個值(2^122 的平方根)之後。只有當理論機率變得不可避免(大約 2^60 UUID)時,使用來自健全操作系統熵的 crypto.getRandomValues 的產生器才會產生衝突,這個數字太大了,您永遠無法達到它。使用弱或重複使用的熵源(常見於實施不佳的 UUID 庫或測試框架)的產生器將在兩者之間產生衝突。
重點:相信數學,審核產生器-ToolAcre 產生器使用瀏覽器的 CSPRNG,這是不能偽造的部分
批次測試可以捕捉返回常數或重播明顯序列的實現,但通過的樣本無法證明未來的唯一性。無論重複的識別碼會損壞資料,生產系統仍應強制執行唯一約束。導入值得特別注意,因為兩個有效的來源系統可能已經包含相同的文字標識符,並可以跨環境複製裝置。 ToolAcre 的測試檢查一批 500 是否包含 500 不同值;這是對此實現的回歸檢查,而不是統計保證。如果出現重複項,請保留證據並檢查產生、匯入、固定裝置和儲存路徑,然後再找出原因。