UUID 產生器

在瀏覽器中產生 UUID:完全隨機的 v4,用於資料庫鍵的按時間排序的 v7,或基於命名空間和名稱的確定性 v5。一次最多產生 1000 個,資料絕不離開您的裝置。

按下產生以抽選
版本
進階選項

需要一個不會與其他人建立的識別碼發生衝突,在一部您從未聽說過的機器上,且無須向任何人請求許可的識別碼嗎?這就是 UUID 的功用。它是一個 128 位元數字,通常以熟悉的 8-4-4-4-12 格式寫成 36 個字元,其整個設計的核心就是即使沒有任何機制協調誰取得哪個,也不會有兩個相同的 UUID。這個免費產生器在您的瀏覽器中產生它們:在「版本」中選擇一個版本,在「數量」中說明您需要多少個,然後按下「產生」。頁面預設開啟的是絕大多數專案所需的單一 v4,因此只需點擊一下即可獲得第一個識別碼。

每個識別碼都由您的瀏覽器透過 Web Crypto API 建構。版本 4 在瀏覽器支援的情況下使用 crypto.randomUUID(),否則使用 crypto.getRandomValues()——這是一個加密等級強度的隨機來源,而不是像 Math.random() 這樣的 JavaScript 偽隨機函式。版本 7 將 48 位元的毫秒時間戳記放在前面,接著是同一毫秒內遞增的 12 位元計數器,然後是 62 個隨機位元,這是 RFC 9562 中描述的排序方法;那個計數器就是為什麼一次產生一千個批次會按順序輸出而不是打亂的原因。版本 1 將時間戳記與設定了多播位元的隨機節點識別碼結合在一起,因此它永遠不會像 1990 年代的原始實作那樣攜帶您的網路卡位址。版本 3 和 5 完全不隨機:它們使用 MD5 和 SHA-1 分別將一個命名空間與一個名稱一起進行雜湊,並且這種雜湊處理同樣是在您的裝置上發生的。沒有任何資料被傳送到伺服器,沒有任何紀錄,而且一旦頁面載入完畢,即使斷開連線它也會繼續運作。

「版本」是決定其他一切的欄位。版本 4 是 122 個隨機位元並且沒有結構——這是預設設定,也是當識別碼只需要具有唯一性時的正確答案。版本 7 保留了 62 個隨機位元,但以它的建立時間開頭,因此一組 v7 可以按其產生順序進行排序;正是這一點使得它成為當識別碼將作為資料庫鍵時的首選版本。版本 1 是原始的基於時間的方案,保留在這裡以供仍要求使用它的系統使用。版本 3 和 5 是特殊的一對:它們是確定性的,這意味著相同的輸入總是產生相同的識別碼,並且它們需要兩個額外的欄位——「命名空間」(標準空間 DNS、URL、OID 和 X.500 之一,或您自己的「自訂」空間)和「名稱」(被識別的字串)。為 v5 提供 URL 命名空間和 https://example.com/a,今天、明天以及在別人的機器上您都會得到相同的 UUID。正因為如此,當選擇 v3 或 v5 時,「數量」會消失:一千份確定性值的副本仍然只是一千份完全相同的副本。對於其他每個版本,「數量」可以從 1 到 1000。

四個開關改變了輸出的形狀,而沒有改變底層的 128 位元。「大寫」將十六進位數字印為大寫字母,「無連字號」提供了某些欄和檔名偏好的 32 字元緊湊形式,而「大括號」將值包裹在 { } 中——這是 Windows 和 .NET 世界稱為 GUID 的形式。在「進階選項」下,urn:uuid: 加上了使其成為正式 URN 的前綴;當它開啟時,會關閉「大括號」和「無連字號」,因為標準只允許一種確切的 URN 形式,那就是帶有連字號的規範形式。「複製格式」決定了取得批次時的連接方式:每行一個、以逗號分隔,或者每個值帶引號並以逗號結尾,以便直接貼上到程式碼的陣列中。結果下方有一行報告位元的隨機性——v4 為 122 位元,v7 為 62 位元——並且對於 v7,還會報告批次中第一個識別碼內編碼的時間戳記,因此值內部的時間是可見的,而不是隱含的。「全部複製」和「儲存為檔案」都遵循「複製格式」的設定。「紀錄」在您的瀏覽器中保留了您最近的 10 個批次:點擊一個即可將其調回,複製或刪除單一項目,或清空全部。「清除」會清空結果但保留您的設定,當識別碼超過 50 個時,清單會變成一個可捲動的區塊而不是五十行。

這個頁面上最重要的一點就是 v4 和 v7 作為主鍵的區別,而且這並不是一個品味問題。資料庫索引是按排序順序保持的 B-tree,新鍵在順序中落入的位置決定了插入操作的代價。v4 鍵是隨機的,因此連續的插入落在索引中互不相關的角落:已滿的頁面被分割,資料庫保留在記憶體中的樹的部分很少是下一次插入所需的部分,最終索引變得比其指向的資料列所對應的規模更大且更破碎化。v7 鍵以當前毫秒開始,因此連續的插入一起落在樹的右邊緣,這是自動遞增整數產生的模式,也是索引結構圍繞其建構的模式。這就是全部的權衡:v7 為您帶來了順序鍵的插入行為,同時保留了讓您最初選擇 UUID 的屬性,即任何人都可以在不請求伺服器的情況下鑄造一個。它的代價是建立時間現在在識別碼內部是可讀的,而這是否要緊是關於您的資料的問題,而不是關於格式的問題。

沒有任何東西會檢查 UUID 的唯一性;其尺寸就是保證。這裡沒有登錄檔,沒有伺服器往返,沒有查閱——產生器產生一個數字並交給您,而其中兩個不發生碰撞的原因僅僅是因為有 2^122 種可能的 v4 值,大約為 5.3 × 10^36。生日問題(birthday problem)是衡量它的最誠實方式:您需要大約 2.7 × 10^18 個識別碼,才能有 50% 的機率使其中任何兩個相符,這相當於在 86 年裡每秒產生十億個新 UUID。精確了解這承諾了什麼和沒承諾什麼是有價值的。這是一種統計上的保證,而非算術上的,並且它僅在底層的隨機性是真實的時候才成立——一個播種不佳的產生器,或一個與其熵池(entropy pool)一起被複製的虛擬機,會以格式無法偵測的方式打破這種保證。版本 7 進一步縮小了這個問題:在單一毫秒內,一個產生器根本不會重複自身,因為計數器是遞增的而不是擲骰子,而在獨立的產生器之間,62 個隨機位元發揮著作用。

UUID 是識別碼,而不是密碼。版本 4 是不可預測的,這誘使人們將其視為秘密——密碼重設連結、不可猜測的 URL、工作階段權杖、API 金鑰。不可預測性是真實的,但保密性是值被處理方式的一種屬性,而識別碼在設計上就是被漫不經心地處理的:它們存在於 URL 中,進入瀏覽器紀錄、伺服器記錄檔、來源標頭和分析中,並被貼上到聊天訊息中。其他版本甚至是更糟糕的選擇。版本 1 和版本 7 都編碼了建立的時間,因此任何持有它的人都能大致知道它是何時產生的,並能縮小與之一起產生的其他事物的範圍。版本 3 和 5 故意是確定性的:一個電子郵件地址的 v5 UUID 不是一個被雜湊的秘密,它是一個任何擁有相同地址的人都可以在一秒鐘內計算出的值。使用 UUID 來命名一個事物。當值必須保持未知時,請使用密碼產生器,或為秘密建構的函式庫中的權杖。

為什麼要選擇這個 UUID 產生器?

UUID 出現的場景,通常是在任何東西能夠確認名字空閒之前,某物必須被命名的時刻。應用程式碼為即將插入的資料列鑄造它們,以便物件在到達資料庫之前就具有識別,並且客戶端可以在寫入操作仍在進行時引用它。分散式系統更加依賴它們:多個服務同時寫入一個資料表,離線的行動客戶端在沒有收訊的地方建立紀錄,一個必須識別其已處理訊息的佇列——所有這些都不能等待共用計數器輪到自己。版本 5 滿足了不同的需求,那是一個從您已經擁有的東西衍生出的穩定識別碼:同一文件、同一 URL 或同一帳號總是映射到相同的 UUID,所以一次匯入可以執行兩次而不複製任何內容。在其他地方,它們僅僅是系統要求的格式——貫穿記錄和追蹤的相關性識別碼,當一千個使用者的上傳進入同一個儲存體時不會發生碰撞的檔名,一個 Windows 登錄機碼,一個必須看起來像真實資料的測試治具。

幾個誠實的限制值得了解。一個批次代表一種版本:「版本」中的值適用於批次中的所有內容,因此一次 v4 產生和一次 v7 產生是兩個不同的批次。這是一個產生器,而不是檢查器——將一個 UUID 貼上進來以回讀它的版本或時間戳記並不是本頁的功能。「儲存為檔案」寫入純文字檔案,而不是 CSV 或 JSON。版本 7 公開揭示它被建立的毫秒級時間,這是一種真正的權衡而不是缺陷,版本 1 以同樣的方式洩漏時間;如果這對您的資料是個問題,版本 4 是那個對誰都不透露任何資訊的版本。標準中有兩個特殊的值不是版本,所以它們不是「版本」中的選項,但您可以從這裡複製它們:nil UUID 即 00000000-0000-0000-0000-000000000000,以及 max UUID 即 ffffffff-ffff-ffff-ffff-ffffffffffff。這個頁面上的一切都遵循 RFC 9562,這是 2024 年取代 RFC 4122 的規範,所以輸出被任何處理 UUID 的函式庫、資料庫或 API 接受。在這些限制內,其保證是強而有力的:每個識別碼都是按照標準、從密碼學安全的隨機性中、在您自己的機器上建構的,而且沒有其他人看過它。

FAQ

我該如何產生一個 UUID?

在「版本」中選擇一個版本,在「數量」中設定您需要多少個,然後按下「產生」。頁面預設開啟一個版本 4 識別碼,這也是大多數專案所需的,所以一個普通的 UUID 離您只有一次點擊之遙。每個值都配有自己的複製按鈕,而「全部複製」可以一次性取得整個批次。

UUID v4 和 v7 之間的差別是什麼?

版本 4 是 122 個隨機位元,完全沒有結構,所以其中任何兩個都沒有相互關係。版本 7 將前 48 位元用於建立的毫秒時間,增加了一個計數器和 62 個隨機位元,並且因此是可排序的:一個批次會按照它們被產生的順序輸出。當識別碼只需要具有唯一性時使用 v4,而當它也將成為資料庫鍵時使用 v7。

我應該使用哪個 UUID 版本?

除非您有理由選擇其他版本,否則選擇版本 4。如果識別碼將成為主鍵且插入效能很重要,請選擇版本 7;如果您需要相同的輸入總是產生相同的識別碼,請選擇版本 5;只有當您需要互動的系統明確要求時,才選擇版本 1。版本 3 是使用 MD5 而不是 SHA-1 的版本 5,為了相容性而存在。

產生的 UUID 真的是隨機且安全的嗎?

隨機性是密碼學安全的:它來自您瀏覽器的 Web Crypto API,透過 crypto.randomUUID() 或 crypto.getRandomValues() 產生,而不是來自 Math.random()。在不可猜測意義上的安全與在保密意義上的安全是兩個不同的問題——UUID 是一個識別碼,它不應該被用作密碼、工作階段權杖或 API 金鑰。

我可以一次產生大量 UUID 嗎?

可以,一次最多可產生 1000 個。設定「數量」並按下「產生」;當值超過五十個時,結果會變成一個可捲動的單一區塊,而不是很長的資料列清單。「全部複製」和「儲存為檔案」會取得整個批次,並按照「複製格式」指定的格式連接——每行一個,用逗號分隔,或者帶上引號以便貼上到陣列中。

為什麼 v3 和 v5 每次都給我相同的 UUID?

因為那正是它們的用途。版本 3 和 5 是確定性的:它們將您給定的命名空間和名稱進行雜湊處理,因此相同的輸入總是產生相同的識別碼,無論在任何機器或任何語言中。這使它們在從您已有的資訊衍生穩定識別碼時非常有用,這也正是為什麼選擇它們時「數量」會被隱藏的原因。

什麼是命名空間和名稱,我應該選擇哪個命名空間?

它們是計算版本 3 或版本 5 UUID 的兩個輸入。「命名空間」表明名稱屬於什麼類型——DNS 用於主機名稱,URL 用於網址,OID 和 X.500 用於相應的目錄方案,或者如果您想提供一個您自己的命名空間 UUID 可以選擇「自訂」,這也是應用程式內部的常見選擇。「名稱」就是字串本身。不同的命名空間對同一名稱會給出完全不同的結果,這就是設定它們的意義。

為什麼對於資料庫主鍵,UUID v7 比 v4 更好?

因為值在索引中落入的位置不同。索引按排序順序保持,而隨機的 v4 鍵會落在其中的任何地方,因此插入操作會在整棵樹上分割頁面,並且保留在記憶體中的部分很少是下一次所需的。v7 鍵以當前毫秒開始,因此連續的插入會一起落在索引的末端,這正是一個順序整數鍵的行為方式——同時仍然允許任何服務在不請求中央計數器的情況下鑄造一個識別碼。

兩個 UUID 會有機會相同嗎?

理論上是的,實際上不會,而了解哪種情況適用是有價值的。沒有任何機制驗證唯一性:僅僅是因為有 2^122 種可能的版本 4 值(大約 5.3 × 10^36),您需要大約 2.7 × 10^18 個識別碼——在 86 年裡每秒十億個——才會使發生哪怕一次碰撞的機會達到 50%。該保證是統計上的而不是絕對的,它依賴於隨機性的真實性,這也是為什麼這個產生器使用 Web Crypto API 而非普通偽隨機函式的原因。

我可以使用 UUID 作為密碼、API 金鑰或工作階段權杖嗎?

不能,這是代價最高昂的錯誤。版本 4 UUID 是不可預測的,但識別碼就像被當作公開資訊一樣處理:它們最終會出現在 URL、瀏覽器紀錄、伺服器記錄檔、來源標頭和分析中。版本 1 和 7 額外揭示了它們的建立時間,而任何知道輸入的人都可以重新計算版本 3 和 5。對於任何必須保密的東西,請使用密碼產生器或專用於秘密的函式庫提供的權杖。

UUID v7 會暴露它的建立時間嗎?

是的,精確到毫秒,這是出於設計而非疏忽——時間戳記正是使 v7 可排序的原因。結果下方的行向您展示了批次中第一個值編碼的時間,因此您可以確切看到暴露了什麼內容。版本 1 也帶有時間戳記。如果建立時間是您不想公開的,版本 4 是完全不包含時間的版本。

UUID v1 會暴露我的 MAC 位址嗎?

在這裡不會。原始方案將機器的網路卡位址作為節點欄位,這也是 v1 名聲的由來,但標準同樣允許一個設定了多播位元的隨機節點識別碼,這就是這個產生器所產生的。您的硬體位址永遠不會被讀取,也永遠不會出現在輸出中。

大寫、無連字號、大括號和 urn:uuid: 會改變什麼?

僅僅是展現形式——底層的 128 位元在每種形式中都是相同的。「大寫」將十六進位數字印為大寫字母,「無連字號」提供緊湊的 32 字元版本,「大括號」用 { } 將值包裹起來,就像 Windows 和 .NET 書寫 GUID 的方式一樣,而 urn:uuid: 加上了使其成為正式 URN 的前綴。urn:uuid: 開啟時會關閉其他兩項,因為標準只定義了一種 URN 形式,那就是帶連字號的規範形式。