通用唯一識別碼

通用唯一識別碼（Universally Unique Identifier，縮寫：UUID）是用於計算機體系中以識別信息的一個128位標識符。
UUID按照標準方法生成時，在實際應用中具有唯一性，且不依賴中央機構的註冊和分配。UUID重複的概率接近零，可以忽略不計。
因此，所有人都可以自行建立和使用UUID，而且幾乎可以確定其不會與既有的識別碼重複。也因為如此，在不同地方產生的UUID可以使用於同一個資料庫或同一個頻道中，而且幾乎不可能重複。
UUID的應用相當普遍，許多計算平臺都提供了對於生成和解析UUID的支援。

**歷史**
1990年代， UUID 原本是用於阿波羅電腦的網絡計算系統，後被用於開放軟件基金會的分散式運算環境。分散式運算環境UUID的初始設計基於網絡計算系統UUID，其設計受 Domain/OS 中定義和使用的（64位）唯一標識符的啟發，這是一個也由阿波羅電腦設計的操作系統。後來，Microsoft Windows平臺採用分散式運算環境設計作為全局唯一標識符（GUID）。 
2005年7月，RFC 4122 為 UUID 註冊了一個 URN 命名空間，並制定了早期的規範。當  作為互聯網工程任務組標準發佈時，國際電信聯盟基於先前的標準和  早期版本標準化了 UUID。

**標準**
UUID 由開放軟件基金會標準化，作為分散式運算環境（DCE）的一部分。
UUID 被紀錄為 ISO/IEC 11578:1996 "Information technology – Open Systems Interconnection – Remote Procedure Call（RPC）" 和後來的 ITU-T Rec. X.667 | ISO / IEC 9834-8：2005 規範的一部份。
互聯網工程任務組公佈了標準 ，技術上等同於 ITU-T Rec. X.667 | ISO/IEC 9834-8。

**格式**
在其規範的文本表示中，UUID 的 16 個 8 位字節表示為 32 個十六進制數字，由連字符 '-' 分隔成五組顯示，形式為「8-4-4-4-12」總共 36 個字符（32 個十六進制數字和 4 個連字符）。
例如：
 123e4567-e89b-12d3-a456-426655440000
 xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
四位數字 M表示 UUID 版本，數字 N的一至三個最高有效位表示 UUID 變體。在例子中，M 是 1 而且 N 是 a（10xx2），這意味著此 UUID 是「變體1」、「版本1」UUID；即基於時間的 。
規範的 `8-4-4-4-12` 格式字符串基於 UUID 的16個字節的“記錄佈局”：
這些字段對應於「版本1」和「版本2」（基於時間的）UUID中的字段，但是「8-4-4-4-12」的表示適用於所有UUID，即使對於生成方式不同的UUID也是如此。
第 3 節要求以小寫形式生成字符，同時對輸入不區分大小寫，儘管一些常用的實現違反了此規則。
Microsoft GUID有時會以大括號表示：
 {123e4567-e89b-12d3-a456-426655440000}
不應將此格式與“Windows註冊表格式”相混淆，後者指的是大括號內的格式。
為UUID定義了統一資源名稱（URN）命名空間。作為URN呈現的UUID如下：
 

**編碼**
UUID 的二進制編碼因系統而異。UUID的變體1是目前世界最常見的UUID，完全以大端序（big-endian）二進制存儲與傳輸 UUID 。
例如，00112233-4455-6677-8899-aabbccddeeff 編碼為字節 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff。
其他系統，特別是 Microsoft 在其 COM/OLE 庫中對 UUID 的字符串表示，使用混合端格式，其中 UUID 的前三組是小端序/小尾序（little-endian），後兩組是 大端序/大尾序（big-endian）。
例如，00112233-4455-6677-8899-aabbccddeeff 編碼為字節 33 22 11 00 55 44 77 66 88 99 aa bb cc dd ee ff。

**變體**
UUID的變體（variant）字段，佔1到3位元。定義了4種變體：- 變體 0 (最顯著位為0，二進制為0xxx2，十六進製表示為016到716) 用於向後兼容已經過時的1988年開發的 Apollo 網絡計算系統（NCS）1.5 UUID 格式。 前6字節是48比特時間戳（從1980年1月1日UTC開始的4微秒的滴答數），隨後2個字節保留，再1個字節是地址族（address family，使用了0..13個情形），最後7個字節是主機ID。這類似於UUID的版本1.- 變體 1 (二進制為10xx2，十六進制為816到b16)，定義在, 或"Leach–Salz" UUID。它是按照大端序作為二進制存儲與傳輸。- 變體 2 (二進制為110x2，十六進制為c16或d16)，RFC稱“保留，微軟公司向後兼容”。早期的Microsoft Windows平臺的GUID使用該格式。和完全使用大端序的變體 1 不同，變體 2 其中一部份按照小端序作為二進制存儲與傳輸。- 形如111x2保留未使用。 
目前的UUID規範使用變體1和2。在文字表示上，兩種變體只有代表變體的位元不同。上面的字段也定義了兩種變體之間的位元組轉換。前三個字段是無正負號的32和16位元數字，需要進行轉換，而後兩個字段是由未解釋的位元組組成，不需要進行轉換。這種轉換同樣適用於版本3、4和5，其中的規範字段與UUID的內容無關。
雖然一些重要的GUID名義上是變體2的UUID，例如元件對象模型（Component Object Model）IUnknown介面的識別碼，但是在微軟Windows軟體中所生成和使用的、被稱為「GUID」的許多識別碼是使用標準的變體1的大端序UUID。目前，Microsoft guidgen工具軟件產生變體1的結果。某些微軟文檔稱GUID與UUID是同義詞，如同中表示UUID「也被稱作GUID」。這些文件表明了雖然「GUID」最初指代微軟所使用的其中一種UUID變體，但現在已經成為UUID的另一個名稱，含括變體1和2。

**版本**
對於「變體（variants）1」和「變體2」，標準中定義了五個版本（versions），並且在特定用例中某些版本可能比其他版本更合適。
版本由字符串中的 M 指示。
版本1的UUID是根據時間和節點ID（通常是MAC地址）生成；版本2的UUID是根據標識符（通常是組或用戶ID）、時間和節點ID生成；版本3、版本5透過對命名空間（namespace）標識符和名稱進行雜湊生成確定性的UUID；版本4的UUID則使用隨機性或偽隨機性生成。

**Nil UUID**
Nil UUID是一個特例，值為 lang=ini ；也就是說，所有位都設置為 0。

**版本1（日期時間和MAC地址）**
版本1的UUID，是根據 60-bit 的時間戳和節點（生成UUID的計算機）的48-bit MAC地址而生成的。
時間戳的是這樣計算的：自公曆首次於天主教會和教皇國以外的地方使用的日期，也就是協調世界時（UTC）1582年10月15日午夜算起，每經過100納秒時間戳加1。聲明時間值在公元3400年左右算術溢位q="it is possible for values to rollover (around A.D. 3400, depending on the specific algorithm used)"，取決於所使用的算法，代表此 60-bit 時間戳是有符號數量。但是，某些軟件（如libuuid庫）將時間戳視為無符號，把溢位時間推遲至公元5236年。ITU-T Rec. X.667所定義的溢位時間為公元3603年rp|v|q="a UUID is ... guaranteed to be different from all other UUIDs generated before 3603 A.D."。
13-bit 或 14-bit「無統一」（uniquifying）時鐘序列擴展了時間戳，以便處理處理器時鐘不能足夠快地前進的情況，或者每個節點有多個處理器和 UUID 生成器的情況。對於每個「版本1」UUID 對應於空間（節點）和時間（間隔和時鐘序列）中的單個點，兩個正確生成的「版本1」UUID 無意中相同的可能性實際上為零。由於時間和時鐘序列總共74位，每個節點 id 可以生成 （ 或 18 sextillion）個「版本1」UUID，每個節點 id 的最大平均速率為每秒 1630 億。
與其他 UUID 版本相比，基於來自網卡的 MAC 地址的「版本1」和「版本2」UUID，部分依賴於由中央註冊機構發佈的標識符，即由 IEEE 發佈給網絡設備製造商的 MAC 地址的組織唯一標識符（OUI）。基於網卡MAC地址的「版本1」和「版本2」UUID 的唯一性還取決於網卡製造商正確地為其卡分配唯一的MAC地址，這與其他製造過程一樣容易出錯。此外，某些作業系統允許終端用戶自訂MAC地址，例如OpenWRT。
使用節點的網絡MAC地址作為節點ID，代表可以透過版本1的UUID逆向找到創建它的計算機。透過在檔案中嵌入UUID，可以實現追蹤到創建或修改這些檔案的計算機。在定位 Melissa 病毒的創建者時就使用了這個隱私漏洞。
如果節點沒有或不希望暴露MAC地址， 確實允許「版本1」（或2）UUID 中的 MAC 地址被隨機的48位節點ID替換。在這種情況下，RFC要求節點ID的第一個八位字節的最低有效位應設置為1，這對應於MAC地址中的多播位，設置它是用於區分隨機生成節點ID的UUID和基於來自網卡的MAC地址的UUID，網卡通常具有單播MAC地址。

**版本2（日期時間和MAC地址，DCE安全版本）**
保留了版本2的UUID用於“DCE security”；但並沒有提供任何細節。因此，許多 UUID 實現省略了「版本2」。但是，「版本2」UUID 的規範由 DCE 1.1 身份驗證和安全服務規範提供。
「版本2」UUID 類似於「版本1」，除了時鐘序列的最低有效8 bits 被“本地域（local domain）”號替換，並且時間戳的最低有效32 bits 由在指定本地域內有意義的整數標識符替換。在 POSIX 系統上，本地域號 0 和 1 分別用於用戶 ID（UIDs）和組 ID（GIDs），其他本地域號用於站點定義。在非 POSIX 系統上，所有本地域號都是站點定義的。
在 UUID 中包含 40 位元的域或標識符（domain/identifier）是有代價的。一方面，40 位元允許每個節點ID有大約1-{zh-hans:萬億; zh-hant:兆;}-個域或標識符的值。另一方面，由於時鐘值被截斷為28個最高有效位，有別於版本1中的60位元，版本2的UUID中的時鐘也改成每429.49秒跳動（tick）一次，略多於7分鐘，而不是版本1中的每100納秒；並且，版本2的時鐘序列僅有6位元，版本1中則有14位元；每7分鐘時鐘週期內，每個節點、域或標識符只能生成64個唯一的UUID，而版本1的時鐘序列值為16,384個。因此，版本2可能不適合用於以節點、域或標識符在約7秒以上1次的速率下生成 UUID 的情況。

**版本3和版本5（基於命名空間名稱）**
「版本3」和「版本5」的 UUID 透過雜湊（hashing）命名空間標識符和名稱生成。版本3使用 MD5 作為-{zh-hans:散列算法; zh-hant:雜湊演算法;}-，版本5則使用 SHA1。
名稱空間標識符本身就是一個 UUID。該規範提供了 UUID 用來表示命名空間為了統一資源定位符（URLs），完整域名、對象標識符和 X.500；但任何所需的UUID都可以用作命名空間指示符。
要確定與給定命名空間和名稱對應的版本3的UUID，命名空間的 UUID 將轉換為字節串，後面加上輸入名稱，然後用 MD5 進行-{zh-hans:散列; zh-hant:雜湊;}-，產生 128 位元。然後將六或七位替換為固定值，即 4 位元的版本號（例如“版本3”的 0011），以及 2 或 3 位元的 UUID 變體號（例如 10 代表的UUID，或 110 代表傳統 Microsoft GUID）。由於預定了6到7位元，因此只有121或122位元用於維持 UUID 的唯一性。
版本5的UUID 和上面類似，但使用 SHA1 而不是 MD5。由於 SHA1 生成 160 位元的摘要，因此在替換版本號和變體號之前會把摘要截斷為 128 位元。
版本3和版本5的UUID具有一個特性：相同名稱空間和名稱將映射到同一個UUID；然而，即使已知其中一項，也無法透過暴力搜索之外的方法從UUID逆向推導出另外一項。 推薦使用版本5（SHA1）而不是版本3（MD5），並建議不要使用任一版本的 UUID 作為安全憑證。

**版本4（隨機）**
版本4的UUID是隨機生成的。與其他 UUID 一樣，其中4位元用於代表「版本4」，2到3位元代表變體號（102 或 1102 分別用於變體 1 和 2）。因此，對於變體1（即大多數 UUID），隨機生成的版本4的UUID會保留6位元用於表示變體號和版本號，其餘122位元用於隨機生成，故版本4變體1的UUID共計有  或（5.3 undecillion）個。版本4變體2的UUID（傳統GUID）則為變體1的一半，因為可用的隨機位少一個，變量消耗 3 位元。
一些偽隨機數發生器缺少必要的熵來產生足夠的偽隨機數。例如，使用偽隨機數生成器的 WinAPI GUID 生成器已被證明可生成遵循可預測模式的 UUID。  建議“在各種主機上生成 UUID 的分佈式應用程序必須願意依賴所有主機上的隨機數源。如果這不可行，則應使用名稱空間變體。”

**衝突**
當多次生成相同的 UUID 並將其分配給不同的指示對象時，就會發生衝突。對於使用來自網卡的唯一MAC地址的標準版本1和2的UUID，只有當實施與標準不同時才可能發生衝突，無論是無意還是故意。
與使用MAC地址生成的版本1和版本2相比，使用隨機生成的節點ID的版本1和版本2、基於散列的版本3和版本5，以及隨機生成的版本4的UUID，即使實現上沒有問題也可能發生衝突，但可能性很小，通常可以忽略。可以基於對生日問題的分析來精確地計算該概率。
例如，如果要有50%的機率至少發生一次衝突，需要生成至少個版本4的UUID，計算如下：
這個數字相當於每秒產生 10 億個 UUID 持續 85 年。每個 UUID 長度為 16 字節，這麼多 UUID 的文件大小約為 45 艾字節（EB），比目前存在的最大數據庫大很多倍，它們都在數百PB的數量級。
若要使發生衝突的機率為p，至少必須生成多少個版本4的UUID可由下式近似計算：
因此，在 103 萬億個版本4 UUID 中找到重複的概率是 （十億分之一）。

**使用**

**檔案系統**
重要用途包括 ext2/ext3/ext4 文件系統用戶空間工具（e2fsprogs 使用 util-linux 提供的 libuuid）、LUKS 加密分區、GNOME、KDE 和 Mac OS X，其中大部分源自 曹子德（Theodore Ts'o）的實現。
Solaris 中 UUID 的一種用途（使用開放軟體基金會的實現）是識別正在運行的操作系統實例，以便在內核崩潰的情況下將故障轉儲數據與故障管理事件配對。
分區標籤和分區UUID都儲存於超區塊中。兩者皆為檔案系統的一部份，而不是分區的一部份。例如，ext2-ext4包含UUID，而NTFS或FAT32則沒有。
超區塊是檔案系統的一部份，因此被完全包含在分區中，因此如果你執行1=dd if=/dev/sda1 of=/dev/sdb1，sda1和sdb1都會擁有相同的標籤和UUID。

**COM**
Microsoft的組件對象模型（COM）中使用了幾種GUID ：- IID - 接口標識符；（在系統上註冊的接口標識符存儲在Windows註冊表中的code|HKEY_CLASSES_ROOT\Interface|lang=reg）- CLSID - 類標識符；（存儲在Code|code=HKEY_CLASSES_ROOT\CLSID|lang=reg）- LIBID - 類型庫標識符；（存儲於Code|code=HKEY_CLASSES_ROOT\TypeLib|lang=reg）- CATID - 類別標識符；（它在一個類中的存在將其識別為屬於某些類別類別，列於Code|code=HKEY_CLASSES_ROOT\Component Categories|lang=reg）

**作為數據庫主鍵**
UUID 通常用作數據庫表中的唯一鍵。
Microsoft SQL Server 版本4 Transact-SQL 中的 NEWID 函數會返回標準隨機版本4的UUID，而 NEWSEQUENTIALID 函數返回類似於 UUID 的 128 位標識符，這些 UUID 會依序遞增，直到下次系統重啟。
另一方面，儘管名稱如此，但 Oracle Database SYS_GUID 函數不會返回標準 GUID；相反，它根據主機標識符和進程或線程標識符返回一個16字節的 128 位 RAW 值，有點類似於 GUID。
PostgreSQL 包含一個 UUID 數據類型，並且可以通過使用模塊中的函數生成大多數版本的UUID。
MySQL 提供了一個 UUID 函數，它生成標準的版本1 UUID。
當 UUID 用作主鍵時，版本3、4和5 UUID 的隨機性以及 版本1和2 UUID 內的字段的排序可能會產生數據庫定位或性能問題。例如，2002年 Jimmy Nilsson 報告說，當用作主鍵的版本4 UUID 被修改為包含基於系統時間的非隨機後綴時，Microsoft SQL Server的性能顯著提高。Nilsson 承認，這種所謂的“COMB”（組合時間和GUID）方法使UUID非標準並且更有可能被複制，但 Nilsson 僅要求在應用程序中的唯一性。透過重新排序和編碼版本1和版本2的UUID，將時間戳放在最前面，可以避免插入所造成的性能損失。
諸如Laravel這樣的部分網路框架支援「時間戳優先」的UUID，可以將UUID有效儲存於索引資料庫中。這種UUID是版本4格式的COMB UUID，但其中前48位元組成了一個時間戳，就像版本1的UUID一樣。其他基於COMB UUID概念的指定格式包括：- ULID，其拋棄了用於表示版本4的4位元，並且預設使用base32編碼。- UUID版本6到8是三種COMB UUID格式的正式提議。

**參見**
 全局唯一標識符（GUID）

**參考文獻 ==