繁體中文

開發者工具 · UUID 產生器

GUID 與 UUID:Microsoft 的大括號、位元組順序和變體解釋

· 背景

uuid 密碼學 瀏覽器 API

以 RFC 順序和 GUID 結構順序呈現的相同 16 位元組,顯示哪些位元組交換
原始 ToolAcre 向量圖

GUID 是 Microsoft 對 UUID 的名稱,但大括號、大寫字母和位元組順序可能會使相同的識別碼在不同平台上看起來有所不同。這篇文章解釋了每個差異以及如何安全地進行比較。

無法跨系統配對的相同 ID — .NET 服務和 Java 服務在一筆記錄上不一致

.NET 服務產生一個 GUID 並將其傳送到 Java 服務,該服務嘗試將該值與 PostgreSQL 中的 UUID 進行比對。字串比較失敗,系統報告標識符不匹配,即使所有三個服務都使用相同的底層 16 位元組。這些差異看似表面上的(大括號、大小寫、位元組順序),但它們會導致字串比較失敗,並混淆未在邊界標準化的積分點。 GUID 是 Microsoft 術語,RFC 9562 稱為 UUID:具有相同位元佈局的 128 位元識別碼。這兩個名稱指的是相同的基本結構,但表示方式的不同讓開發人員感到驚訝。了解混亂的根源可以防止整合錯誤。

GUID 是 UUID — 共用 128 位元格式以及命名差異的來源

GUID 代表全域唯一識別符和全域唯一標識符,是 Microsoft 用於 RFC 標準所謂的 UUID 的名稱。 128 位元版面配置和版本 /variant 系統相同。 RFC 4122 和 RFC 9562 指定 UUID 格式和意義; Microsoft 實作了它們並使用術語 GUID。命名差異是歷史性的:在 IETF 對 UUID 進行標準化之前,Microsoft 使用了 GUID,而 Microsoft 術語一直停留在 .NET 生態系統中。在位元級別,GUID 和 UUID 是完全可以互換的。在格式層級上,它們的表示方式有所不同:.NET 程式碼通常使用大括號和大寫字母編寫 GUID,而 RFC 規範 UUID 使用小寫且不使用大括號。

大括號和大寫字母 - 註冊表樣式的 {XXXXXXXX-...} 形式以及如何對其進行規範化

規範 RFC 形式的 UUID 寫作八個、四個、四個、四個和十二個小寫十六進製字符,並用連字符分隔:550e8400-e29b-41d4-a716-446655440000。 .NET GUID 通常以大括號和大寫字母顯示:{550E8400-E29B-41D4-A716-446655440000}。大括號來自 Windows 註冊表格式;大寫是一種顯示約定。兩種形式都表示相同的 128 位元。要將 .NET 中的 GUID 與 PostgreSQL 中的 UUID 進行匹配,請去掉大括號並標準化大小寫,然後比較字串。 ToolAcre 格式良好的檢查接受規範形式並自動刪除大括號。規範化是一種保留所有意義的小型文字轉換。

混合尾數字節順序 — 前三個欄位如何以小尾數儲存在 GUID 結構中,以及為什麼 Guid.ToByteArray 與 RFC 位元組順序不同

GUID 和 UUID 之間的危險差異在於位元組順序。 RFC 9562 指定前三個欄位(8、4 和 4 個十六進位組)以大端(網路)位元組順序儲存。 .NET Guid 結構以小端儲存前三個欄位:在寫入儲存之前位元組會反轉。當由 .NET Guid.ToByteArray() 寫入並由符合 RFC 的程式碼解釋時,相同的 16 個位元組會產生完全不同的文字表示形式。 RFC 位元組順序中的 UUID 550e8400-e29b-41d4-a716-446655440000 儲存為位元組 55 0e 84 00 e2 9b 41 d4 a7 16 44 66 5 40 e2 9b 41 d4 a7 16 44 66 5 40 4 4004。

傳統的 Microsoft 變體 — 第四組第一個字元中的 c 或 d 的含義

除了位元組順序之外,舊版 Microsoft 識別碼有時還會使用非標準變體欄位。其中 RFC 9562 指定第四組的第一個字元必須是 8、9、a 或 b,舊版 Microsoft GUID 可能使用 c、d、e 或 f。這些仍然是有效的 UUID,但它們符合 RFC 標準化之前的遺留變體。如果您在第四組第一個字元中遇到帶有 c 或 d 的 GUID,則您有一個不符合 RFC 變體位元的有效 128 位元值。現代 .NET 產生符合 RFC 的 GUID,因此新識別碼不應出現此問題。遺留變體位很少見,但識別起來很重要。

工作範例 - 以 RFC 順序和 GUID 結構順序呈現的相同 16 位元組,準確顯示哪些字元交換

取得 UUID 550e8400-e29b-41d4-a716-446655440000 並使用小端約定將其轉換為 .NET GUID 位元組陣列形式。依照 RFC 順序,位元組為:第一個欄位 (550e8400) 等於 55 0e 84 00,第二個欄位 (550e8400) 等於 55 0e 84 00,第二個欄位 (550e8400) 等於 55 0e 84 00,第二個欄位 (550e8400) 等於 55 0e 84 00,第二個欄位 (e29b) 等於 e2 9b,第三個欄位 (41d4) 等於 41 d4,第四個和第五個等於 a7 16 44 6 5500在 .NET 小端:第一個欄位變成 00 84 0e 55,第二個變成 9b e2,第三個變成 d4 41,其餘部分保留為大端。完整的位元組數組為 00 84 0e 55 9b e2 d4 41 a7 16 44 66 55 44 00 00。如果 Java 系統按照 RFC 順序讀取這些字節,則會將它們解釋為 00840e55-9be2-d441-a716-446655440000。

這不包括什麼 - SQL Server 的 NEWSEQUENTIALID 和排序,它們是它們自己的儲存主題

SQL Server NEWSEQUENTIALID 函數行為及其特定標識符排序屬性是儲存層和資料庫特定的主題。這篇文章重點討論應用程式和序列化層級的格式和位元組順序差異。深層特定於資料庫的 UUID 處理和位元組順序問題最好在特定於該資料庫平台的檔案中解決。不同的資料庫系統對 UUID 儲存、索引、排序和本機支援有不同的方式和途徑。有些資料庫會自動偵測版本和變體位,而其他資料庫則需要在系統和儲存之間的邊界進行明確類型宣告和位元組順序處理。

重點:在邊界處標準化 — ToolAcre 檢查接受規範形式,這是交換 ID 時要標準化的形狀

當識別碼跨越 .NET/non-.NET 系統邊界時,在邊界處進行標準化。去掉大括號,一致地標準化大小寫,如果位元組來自 .NET Guid.ToByteArray(),則位元組交換前三個欄位。規範的 RFC 形式是參考標準:八個、四個、四個、四個和十二個小寫十六進製字符,帶連字符,無大括號,大端字節順序。與 .NET 系統交換時,應商定規範化形式並在整合程式碼中明確應用轉換。記錄位元組順序處理並徹底測試轉換。 GUID 和 UUID 之間的核心基本相似之處意味著大多數 128 位元是相同的。