開發者工具 · UUID 產生器
從 128 位元到 36 字元:UUID 文字編碼的工作原理
· 工作原理
uuid 密碼學 瀏覽器 API
UUID 是 16 位元組,但其熟悉的形式是 36 個字元。這篇文章解釋了十六進制加倍、連字符、大小寫規則以及人們在標準形式太長時使用的較短編碼。
為什麼列比值寬 - 16 字節值在文字中花費 36 個字符,以及這對 URL 和存儲意味著什麼
當您選擇 UUID 格式時,儲存列寬度會爆炸。 128 位元值是 16 個位元組,但其文字表示形式取決於編碼:十六進位(帶連字符的 36 個字符,不含連字符的 32 個字符)、base64url(22 個字符)、base58(22-23 個字符)、Crockford base32(26 個字符)。如果您的架構將 UUID 儲存為 VARCHAR(36),則每行將花費 36 個字元。在具有 10 億行且沒有其他列的表中,文字開銷為 36 GB,而二進位開銷為 16 GB。這種選擇不僅僅是裝飾性的,而且是實用性的。它會影響查詢大小、網路往返和快取壓力。規範格式為 36 個字元:八個十六進位數字、連字號、四個十六進位數字、連字號、四個十六進位數字、連字號、四個十六進位數字、連字號、十二個十六進位數字。
十六進位將所有內容加倍 - 每個位元組變成兩個字符,四個連字符完成 36
每個位元組恰好變成兩個十六進位字元(0–9,a–f)。出於可讀性和首次指定 UUID 時遺留的原因,使用連字號。十六進位編碼使位元組數加倍:16 位元組變成 32 十六進位數字加上 4 連字號。它是最慢的編碼,也是最長的編碼,但是人類可讀並到處都受支持。大小寫規則:RFC 9562 要求規格輸出使用小寫字母,但輸入不區分大小寫。儲存大寫字母會浪費標準化的機會,因此儲存小寫字母並在輸入時不區分大小寫進行比較。 Base64url 編碼使用 64 字元字母(A–Z、a–z、0–9、減號、底線)將三個位元組表示為四個字元。十六個位元組變成 21 個字元加上 1 個填充字符,總共 22 個字元。 Base64url 刪除 URL 中保留的填充和標準字元(加號和斜線)。
大小寫規則 - 輸出小寫,輸入不區分大小寫,以及為什麼混合大小寫比較會導致無提示不匹配
與十六進位相比,base64url 格式的 UUID 可以保存 14 個字符,並在沒有百分比編碼的 URL 中有效。缺點是可讀性較差(小寫字母看起來像數字;b、8、B 和 8 很容易混淆)。 Base58 由比特幣和其他區塊鏈使用,並刪除不明確的字符(0、O、I、l),使結果為 22–23 字符,同時保持可讀性。 Crockford base32(專為類似於 ISBN 的校驗和格式而設計)使用 26 字符,並優先考慮正確性而不是簡潔性。 Microsoft GUID 位元組順序陷阱適用於某些資料庫中的 UUID 儲存。 RFC 9562 指定所有位元組的網路位元組順序(大端)。某些 Microsoft SQL Server 設定在前三個欄位中儲存具有小端位元組順序的 GUID。
較短的編碼 — 22 字元處的 base64url、base58 和 Crockford base32,以及它們在可讀性和複製貼上安全性方面的權衡
以大端和小端儲存的相同 128 位元值會產生不同的十六進位字串。儲存為 Microsoft GUID 的 UUID 550e8400-e29b-41d4-a716-446655440000 可能會被檢索為 00840e55-9be2-d441-a716-446655440000 和顛倒位元組(倒值)。如果您的系統在符合 RFC 的系統和 Microsoft 系統之間建立橋樑,您必須意識到這一點,並在邊界處進行規範化或記錄您在每個欄位中使用的格式。工作範例:十六進位的 v4 UUID 9b2e4f1a-4f3e-4c1a-8a7d-1b2c3d4e5f60 佔用 36 個字元。作為 16 個位元組,它是 9b 2e 4f 1a 4f 3e 4c 1a 8a 7d 1b 2c 3d 4e 5f 60。在 base64url 中:分割成三位元組區塊,轉換為 base64,去除填充:my5PGk8-TBqKfRssPTRPX2A。不含連字符的十六進位:9b2e4f1a4f3e4c1a8a7d1b2c3d4e5f60(32 個字元)。
Microsoft 位元組順序陷阱 — GUID 的前三個欄位如何以小端存儲,因此相同的位元組可以列印為兩個不同的字串
Base64url 儲存 14 個字元; base58 會保存大致相同的內容;十六進位是標準。根據您的用例進行選擇:如果標識符出現在 URL 中並每個字元都很重要,請使用 base64url;如果它出現在人類閱讀的日誌和 UI 中,請使用十六進位規範形式;如果您正在建立校驗和很重要的區塊鏈系統或分散式系統,請使用 base58 或 Crockford base32。選擇列類型時,請儲存針對您的實際存取模式進行最佳化的值。如果您經常查詢 UUID 並需要不區分大小寫的匹配,請儲存二進位 (16) 並讓資料庫處理表示形式。如果按子字串查詢(搜尋以前綴開頭的 UUID),則十六進位在偵錯輸出中更具可讀性。
工作範例-一個以位元組、規範十六進位和縮寫形式編寫的標識符,顯示每個轉換步驟
如果匯出至 CSV 並透過電子郵件傳送給非技術用戶,則十六進位更容易識別。如果您空間有限(具有本機快取的行動應用程式),base64url 或 base58 可以節省頻寬。 ToolAcre 產生器輸出規範的 36 字元十六進位格式;如果您需要不同的編碼,格式正確的檢查仍然有效,因為它會在檢查格式之前規範任何有效的表示方式。在編碼或解碼數百萬個 UUID 時,效能考慮因素很重要。十六進位編碼很簡單:每個位元組在 O(1) 時間內將每個位元組轉換為兩個字元。解碼同樣簡單。 Base64 編碼和解碼使用查找表,速度稍慢(大致比每位元組十六進位慢 2–3 倍,取決於硬體和實作)。 Base58 的速度要慢得多,因為它本質上是基數轉換並需要模運算。
這不包括 - 資料庫列選擇,例如本機 uuid 類型與二進位 (16),單獨介紹
如果您的系統在熱循環(高頻標識符產生、批量匯出)中對 UUID 進行編碼或解碼,則十六進位速度更快。如果編碼很少發生且 14 字元節省很重要,則 base64url 是一個合理的權衡。 ToolAcre 產生器輸出十六進制,因此您可以在不犧牲相容性的情況下獲得效能優勢。字串比較語意因編碼而異。十六進位 UUID 可以作為字串進行比較: 550e8400-e29b-41d4-a716-446655440000 < 550e8400-e29b-41d4-a716-446655440001 (字典比較有效)。二進位 UUID 可以按位元組進行比較:逐字節比較與數字比較相同。但是,Base64url 和 base58 編碼的 UUID 在字典字串比較中不保留數字順序。如果您的系統依賴 UUID 的字典排序(建立索引或資料庫鍵的令人驚訝的常見模式),則必須使用十六進位、二進位或可排序的 UUID 變體(v6 或 v7)。
重點:在邊界上保持規範形式 - ToolAcre 產生器輸出標準 36 字元 UUID,並其檢查接受該形式的字串
ToolAcre 產生器目前產生 v4 UUID,無法依編碼順序排序。互通性需要對單一編碼進行標準化。同時接受十六進位、base64 和 base58 UUID 的系統必須在處理之前將所有輸入標準化為規範形式。這是可能的,但增加了複雜性。外部 API 或資料庫可能需要特定的編碼:一些 API 期望 urn:uuid: 帶有前綴的十六進制,其他 API 期望無連字符的十六進制,還有一些 API 期望 base64url。在 API 合約中清楚記錄您系統的 UUID 編碼期望值。 ToolAcre 產生器始終輸出規範的十六進位;如果您需要其他編碼,請明確執行轉換並向團隊記錄權衡(空間、效能、可讀性、可排序性)。