由 JavaScript 產生的 UUID,是一個 128 位元的識別碼,以標準的 8-4-4-4-12 格式,寫成 32 個十六進位數字——例如 f47ac10b-58cc-4372-a567-0e02b2c3d479——其中第 13 個十六進位數字固定為 4(代表版本),第 17 個則固定為 8、9、a 或 b(代表變體),因此 128 個位元中有 6 個被保留下來,剩下 122 個位元可以自由用於隨機性。正是這 122 個位元的隨機資料量,讓 v4 版本的 UUID,在任何實際應用程式會產生的量級下,實質上不會發生碰撞。在 JavaScript 中,填滿這 122 個位元最安全的做法,是使用 Web Crypto API 的 crypto.getRandomValues,它會從瀏覽器具備密碼學安全性的亂數產生器中取值。「UUID」這個簡稱代表 Universally Unique IDentifier(通用唯一識別碼),而 v4 這個變體,是 RFC 4122 及其在 2024 年的後繼規範 RFC 9562 中所定義、完全隨機的版本——這種識別碼可以在任何裝置上、在任何地方獨立產生,不需要向中央登錄機構回報。正是這種不需要協調的特性,讓許多 JavaScript 技術堆疊,會預設用 v4 來產生資料庫鍵值、冪等性權杖、日誌關聯 ID 與檔案名稱。

UUID v4 實際上長什麼樣子
每一個 v4 版本的 UUID,都是一個 128 位元的值,以 32 個十六進位字元表示,分成 8、4、4、4、12 個數字一組的五個區塊,中間用連字號分隔。因此標準的文字形式長度是 36 個字元——32 個十六進位數字加上 4 個連字號。在這 128 個位元中,恰好有 6 個不是隨機的:4 個位元用來編碼版本,2 個位元用來編碼變體。因為 v4 會把版本值 4 存在第 13 個十六進位數字的高半位元組中,所以這個數字永遠是字元 4。變體位元則位於第 17 個十六進位數字的最高兩個位元中,因此這個數字永遠是 8、9、a 或 b 其中之一。任何人只要檢查這兩個位置,就能辨識出一個 v4 版本的 UUID——這就是整份規格的指紋所在。
能夠辨識版本與變體,也讓您可以一眼看出 v4 與其他 UUID 版本的差別。第 13 個十六進位數字,會依照版本不同而編碼成 1、3、4、5 或 7;第 17 個數字的規則則適用於所有版本,因為變體欄位是共用的。這種以連字號分組的外形、固定的版本半位元組,以及固定的變體半位元組,三者共同定義了在程式碼審查、日誌管線,或資料庫欄位限制中,「看起來像 v4」到底代表什麼。
為什麼隨機來源在 JavaScript 中很重要
v4 版本 UUID 中那 122 個隨機位元,必須來自某個地方,而這個來源非常重要。一段簡短的 JavaScript 程式碼,可以呼叫 Math.random() 並格式化輸出,產生一個看起來像 UUID 的字串,但 Math.random 並不具備密碼學安全性:它的確定性強到,看過幾筆輸出結果的攻擊者,有時候可以預測後續的值,而且這個演算法在不同引擎之間也不一致。瀏覽器安全的做法是 crypto.getRandomValues,它取用的,是與 TLS 交握及其他安全關鍵 API 相同的密碼學安全亂數產生器(CSPRNG)。
這正是為什麼UUID 產生器所產生的識別碼,可以安全地暴露在網址、日誌與用戶端程式碼中的核心原因:每一個值,都是在您的分頁中用 crypto.getRandomValues 產生出來的。用 CSPRNG 取出的這 122 個位元,讓每一次輸出,在統計上都與前一次輸出獨立——沒有共用的種子、沒有時鐘、沒有 MAC 位址,也沒有混入任何命名空間。正是這項特性,讓兩個互不相關的服務,可以在同一時刻各自產生識別碼,卻仍然有信心不會發生碰撞。跳過 CSPRNG 所付出的代價,並不只是理論上的:一個可被預測的識別碼,可能被猜中、被重放,或是在不同請求之間被關聯起來,而這正是安全審查在拒絕以弱隨機性建構的識別碼時,所指出的那種失效模式。
在您的瀏覽器中產生 UUID
不寫任何一行程式碼,就能產生單一 UUID 或一整批 UUID 最快的方法,就是這個瀏覽器內的 UUID 產生器。整個流程都在本機執行,因此識別碼在任何網路往返之前就已經準備好。
- 開啟 UUID 產生器,輸入您想要的 UUID 數量,範圍從 1 到 100。
- 如果您的資料庫欄位或程式碼風格需要不同的文字形式,可以切換 大寫 讓十六進位數字變成大寫,或者切換 移除連字號 拿掉這四個分隔符號,產生一個連續的 32 字元字串。
- 點擊 產生。清單就會重新整理,顯示從您瀏覽器的 CSPRNG 取出的全新 v4 版本 UUID。
- 把滑鼠移到任何一列上,複製那一個單獨的 UUID,或使用 全部複製 一次把整批結果都複製到剪貼簿。
因為這個工具是在您的分頁中執行,您可以無限次重複這個步驟:每點擊一次「產生」,就會產生全新的一批,而且您可以在每次執行之間變更格式切換選項,不會遺失先前產生的值。對於也想在實際程式碼中測試這些值的開發者,JavaScript 練習場 是一個實用的搭配工具——把產生出來的 UUID 貼進一段程式碼片段中,在上線之前,用您真正的驗證邏輯測試它。
選擇輸出格式
有三個切換選項,決定了 UUID 產生器回傳的文字形式。它們都不會改變底層的 128 位元數值,因此這只是純粹依照您下游系統的需求所做的選擇。
| 切換選項 | 文字形式 | 範例 | 是否為相同的值? |
|---|---|---|---|
| 預設 | 小寫,含連字號 | f47ac10b-58cc-4372-a567-0e02b2c3d479 | 是 |
| 大寫 | 大寫十六進位,含連字號 | F47AC10B-58CC-4372-A567-0E02B2C3D479 | 是 |
| 不含連字號 | 小寫,不含分隔符號 | f47ac10b58cc4372a5670e02b2c3d479 | 是 |
| 兩者皆是 | 大寫十六進位,不含分隔符號 | F47AC10B58CC4372A5670E02B2C3D479 | 是 |
資料庫欄位經常儲存標準的 36 字元形式,因為它符合規格,但有些權杖系統、標頭值與內嵌識別碼,偏好使用 32 字元、不含連字號的形式,以節省空間或配合固定寬度的欄位。如果您的技術堆疊,用不區分大小寫的方式比較 UUID,大寫選項就沒有影響;如果是用區分大小寫的方式比較,請堅持使用小寫,以免最後得到兩個外觀不同、卻代表同一個識別碼的字串。
什麼時候該選擇 UUID v4
對於任何需要由兩個系統各自獨立產生、不需要協調的識別碼而言,版本 4 都是正確的預設選擇——這正是 JavaScript 開發者經常遇到的情境。
| UUID 版本 | 位元來源 | 典型的 JavaScript 使用情境 |
|---|---|---|
| v1 | 時間戳記 + MAC 位址 | 在 JS 中很少使用;可能洩漏主機資訊 |
| v3 | 命名空間 + 名稱的 MD5 雜湊值 | 由已知輸入產生確定性的識別碼 |
| v4 | 來自 CSPRNG 的 122 個隨機位元 | 資料庫鍵值、冪等性權杖、追蹤 ID、檔案名稱 |
| v5 | 命名空間 + 名稱的 SHA-1 雜湊值 | 與 v3 相同,但使用更強的雜湊演算法 |
| v7 | 毫秒時間戳記 + 隨機尾端 | 為索引局部性提供時間排序的鍵值 |
實際的使用案例,都與 v4 相符:需要在同步之前先建立紀錄的分散式與離線優先系統、防止 API 呼叫重複的冪等性鍵值、貫穿整個日誌管線的關聯 ID,以及跨服務時不得發生碰撞的物件或檔案名稱。對這些情境而言,不含任何時鐘、MAC 位址或命名空間輸入,正是一項優點——因為根本沒有可以洩漏的東西,也沒有需要協調的東西。
值得特別一提的唯一例外,是 UUIDv7。如果您把 UUID 儲存在依主鍵建立索引的資料庫中,並且在意索引的局部性——也就是新寫入的資料,總是落在索引尾端附近,而不是隨機散落各處——那麼 v7 這種以時間排序的前置部分,會是更好的選擇。而對於較常見的、不要求順序的唯一性需求,v4 仍然是預設選擇。
僅在瀏覽器中產生與安全性
這個產生器所產生的每一個 UUID,都是在您的瀏覽器分頁中,用 crypto.getRandomValues 於本機計算出來的。您產生或複製的任何內容,都不會傳送到伺服器,因此這個工具無論用於正式環境的識別碼,還是內部機密資料,都可以安全使用。這項保證,是來自實作方式本身,而不是來自一項隱私承諾:這個頁面從不會對任何 UUID 後端開啟網路連線,而剪貼簿輸出,是這個值唯一會前往的地方。
為了讓碰撞的數學更具體,我們就以 122 個隨機位元為例。生日界限——也就是一組集合中,至少出現一次重複的機率達到 50% 的那個點——大約是 2.71 × 10^18。把這個數字除以每秒 10^9 個 UUID,再除以每年 31,536,000 秒,會得到大約 86 年——也就是說,以每秒十億個 UUID 的速度持續產生,大約要經過這麼久,才會讓出現一次重複的機率超過一半。這正是分散式系統,在不跨機器協調的情況下,把 v4 版本的 UUID 視為實質上唯一的根本原因,也正是讓它們能在瀏覽器分頁中安全產生的那項特性。
對 JavaScript 開發者而言,實際上的結論很簡短。對於任何需要無法被猜測的用途,請跳過 Math.random()。在程式碼中使用 crypto.getRandomValues(),而當您需要一個值、卻來不及自己寫程式碼片段時,就使用 UUID 產生器——輸出結果,是同樣的 122 位元隨機識別碼,只是產生的過程中沒有經過網路往返。如果您需要核對規格細節,標準的參考文件是 RFC 4122,並由 RFC 9562 更新,其中確切定義了版本與變體位元該如何設定。