通用唯一識別碼
本條目存在以下問題,請協助改善本條目或在討論頁針對議題發表看法。
|
通用唯一識別碼(英語:Universally Unique Identifier,縮寫:UUID)是用於計算機體系中以識別信息數目的一個128位標識符,還有相關的術語:全局唯一標識符(GUID)。
根據標準方法生成,不依賴中央機構的註冊和分配,UUID具有唯一性,這與其他大多數編號方案不同。重複UUID碼概率接近零,可以忽略不計。
歷史編輯
UUID最初用於 Apollo 網絡計算系統(NCS),後來用於開放軟件基金會(OSF)分布式計算環境(DCE)。DCE UUID的初始設計基於NCS UUID,其設計受 Domain/OS 中定義和使用的(64位)唯一標識符的啟發,這是一個也由 Apollo Computer 設計的操作系統。後來,Microsoft Windows 平台採用 DCE 設計作為全局唯一標識符(GUID)。 RFC 4122 為 UUID 註冊了一個 URN 命名空間,並制定了早期的規範。當 RFC 4122 作為 IETF 標準發布時,ITU 基於先前的標準和 RFC 4122 早期版本標準化了 UUID。
標準編輯
UUID 由開放軟件基金會(OSF)標準化,作為分布式計算環境(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 規範中。
互聯網工程任務組(Internet Engineering Task Force,IETF)公布的標準 RFC 4122,技術上等同於 ITU-T Rec. X.667 | ISO/IEC 9834-8。
定義編輯
UUID是由一組32位數的16進位數字所構成,故UUID理論上的總數為1632=2128,約等於3.4 x 1038。也就是說若每納秒(ns)產生1萬億個UUID,要花100億年才會將所有UUID用完。
UUID的標準型式包含32個16進位數字,以連字號分為五段,形式為 8-4-4-4-12 的32個字元。範例:
- 550e8400-e29b-41d4-a716-446655440000
UUID亦可刻意重複以表示同類。例如說微軟的COM中,所有元件皆必須實作出IUnknown介面,方法是產生一個代表IUnknown的UUID。無論是程序試圖存取元件中的IUnknown介面,或是實作IUnknown介面的元件,只要IUnknown一被使用,皆會被參考至同一個ID:00000000-0000-0000-C000-000000000046。
格式編輯
在其規範的文本表示中,UUID 的 16 個 8 位字節表示為 32 個十六進制(基數16)數字,顯示在由連字符分隔 '-' 的五個組中,"8-4-4-4-12" 總共 36 個字符(32 個字母數字字符和 4 個連字符)。例如:
123e4567-e89b-12d3-a456-426655440000xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
四位數字 M表示 UUID 版本,數字 N的一至三個最高有效位表示 UUID 變體。在例子中,M 是 1 而且 N 是 a(10xx),這意味着此 UUID 是「變體1」、「版本1」UUID;即基於時間的 DCE/RFC 4122 UUID。
規範的 `8-4-4-4-12` 格式字符串基於 UUID 的16個字節的「記錄布局」:
| Name | Length (bytes) | Length (hex digits) | Contents |
|---|---|---|---|
| time_low | 4 | 8 | 整數:低位 32 bits 時間 |
| time_mid | 2 | 4 | 整數:中間位 16 bits 時間 |
| time_hi_and_version | 2 | 4 | 最高有效位中的 4 bits「版本」,後面是高 12 bits 的時間 |
| clock_seq_hi_and_res clock_seq_low | 2 | 4 | 最高有效位為 1-3 bits「變體」,後跟13-15 bits 時鐘序列 |
| node | 6 | 12 | 48 bits 節點 ID |
這些字段對應於「版本1」和「版本2」基於時間的 UUID 中的字段,但是相同的 "8-4-4-4-12" 表示用於所有UUID,即使對於構造不同的UUID也是如此。
RFC 4122 第 3 節要求以小寫形式生成字符,同時對輸入不區分大小寫,儘管一些常用的實現違反了此規則。
Microsoft GUID有時用周圍的大括號表示:
{123e4567-e89b-12d3-a456-426655440000}
不應將此格式與「 Windows註冊表格式」 混淆,後者指的是花括號內的格式。
RFC 4122 為UUID 定義了統一資源名稱(URN)命名空間。作為URN呈現的UUID如下:
urn:uuid:123e4567-e89b-12d3-a456-426655440000
編碼編輯
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。
版本編輯
對於「變體(variants)1」和「變體2」,標準中定義了五個版本(versions),並且在特定用例中每個版本可能比其他版本更合適。
版本由 M 字符串中指示。
版本1 - UUID 是根據時間和節點 ID(通常是MAC地址)生成;
版本2 - UUID是根據標識符(通常是組或用戶ID)、時間和節點ID生成;
版本3、版本5 - 確定性UUID 通過散列(hashing)命名空間(namespace)標識符和名稱生成;
Nil UUID編輯
Nil UUID是一個特例,值為 00000000-0000-0000-0000-000000000000 ;也就是說,所有位都設置為 0。
版本1(日期時間和MAC地址)編輯
「版本1」連接「節點」 的 48-bit MAC地址(即生成UUID的計算機),具有60位時間戳,自1582年10月15日午夜起協調世界時(UTC)以來的100納秒間隔數,公曆首次採用的日期。RFC 4122聲明時間值在公元3400左右滾動,取決於所使用的算法,這意味着 60-bit 時間戳是有符號數量。但是,某些軟件(如libuuid庫)將時間戳視為無符號,將轉存時間設置為 5236 AD。
13-bit 或 14-bit「無統一」(uniquifying)時鐘序列擴展了時間戳,以便處理處理器時鐘不能足夠快地前進的情況,或者每個節點有多個處理器和 UUID 生成器的情況。對於每個「版本1」UUID 對應於空間(節點)和時間(間隔和時鐘序列)中的單個點,兩個正確生成的「版本1」UUID 無意中相同的可能性實際上為零。由於時間和時鐘序列總共74位,每個節點 id 可以生成 ( )或 18 sextillion(大數名詞,千的七次方,十萬億億)個「版本1」UUID,每個節點 id 的最大平均速率為每秒 1630 億。
與其他 UUID 版本相比,基於來自網卡的 MAC 地址的「版本1」和「版本2」UUID,部分依賴於由中央註冊機構發布的標識符,即 MAC 地址的組織唯一標識符(OUI)部分,由 IEEE 發布給網絡設備製造商。基於網卡 MAC地址的「版本1」和「版本2」UUID 的唯一性還取決於網卡製造商正確地為其卡分配唯一的 MAC地址,這與其他製造過程一樣容易出錯。
使用節點的網絡 MAC 地址作為節點 ID ,意味着可以將「版本1」UUID 追溯回創建它的計算機。文檔有時可以跟蹤到通過文字處理軟件嵌入到它們中的 UUID 創建或編輯它們的計算機。在找到 Melissa 病毒的創建者時使用了這個隱私漏洞。
RFC 4122 確實允許「版本1」(或2)UUID 中的 MAC 地址被隨機的 48 位節點 id 替換,因為該節點沒有 MAC 地址,或者因為不希望暴露它。在這種情況下,RFC要求節點 id 的第一個八位字節的最低有效位應設置為 1,這對應於MAC地址中的多播位,並且設置它用於區分隨機生成節點 id 的 UUID 和基於來自網卡的 MAC 地址的 UUID,網卡通常具有單播 MAC 地址。
版本2(日期時間和MAC地址,DCE安全版本)編輯
RFC 4122 保留了「DCE security」 UUID 的「版本2」;但它沒有提供任何細節。因此,許多 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 bits 域/標識符(domain/identifier)的能力需要權衡。一方面,40 bits 允許每個節點 id 有大約1萬億個 域/標識符 值。另一方面,時鐘值被截斷為 28 個最高有效位,而「版本1」中為60 bits;「版本2」的 UUID 中的時鐘每429.49秒進行一次標記(tick),略多於7分鐘,而不是「版本1」中的每 100 納秒;並且,「版本2」僅 6 bits 時鐘序列,「版本1」中 14 bits;每7分鐘時鐘周期內,每個 節點/域/標識符(node/domain/identifier)只能生成64個唯一的UUID,而版本1的時鐘序列值為16,384個。 因此,「版本2」可能不適合於以每個 節點/域/標識符 生成 UUID 的情況,其速率約 7秒以上1次。
版本3和版本5(基於命名空間名稱)編輯
「版本3」和「版本5」的 UUID 被生成雜湊(hashing)一個命名空間標識符和一個名稱。「版本3」使用 MD5 作為散列算法,「版本5」使用 SHA1。
名稱空間標識符本身就是一個 UUID。該規範提供了 UUID 用來表示命名空間為了統一資源定位符(URLs),完整域名、對象標識符和 X.500 輕型目錄訪問協議 ;但任何所需的UUID都可以用作命名空間指示符。
要確定與給定命名空間和名稱對應的「版本3」UUID,命名空間的 UUID 將轉換為字節串,與輸入名稱連接,然後用 MD5 進行散列,產生 128 bits。然後將六或七位替換為固定值,即 4-bit 版本(例如「版本3」的 0011),以及 2-bit 或 3-bit UUID「變體(variant)」(例如 10 指示RFC 4122 UUID,或 110 指示傳統 Microsoft GUID)。由於預定了6或7 bits,因此只有121 或 122 bits 有助於 UUID 的唯一性。
「版本5」UUID 類似,但使用 SHA1 而不是 MD5。由於 SHA1 生成 160-bit 摘要,因此在替換版本和變體位之前,摘要將截斷為 128-bits。
「版本3」和「版本5」UUID 具有相同名稱空間和名稱,將映射到同一 UUID ;除了暴力搜索之外,命名空間和名稱都不能從 UUID 中確定。
RFC 4122 推薦「版本5」(SHA1)而不是「版本3」(MD5),並建議不要使用任一版本的 UUID 作為安全憑證。
版本4(隨機)編輯
隨機生成「版本4」UUID。與其他 UUID 一樣,4-bit 用於指示「版本4」,2-bit 或 3-bit 用於指示變體(variant)(10 或 110 分別用於 變體 1 和 2)。因此,對於變體1(即大多數 UUID),隨機「版本4」UUID 將具有 6 個預定的變體和版本位,為隨機生成的部分留下122位,「版本4」變體1 UUID 可能共計 或 (5.3 undecillion,大數名詞)個。「版本4」變體2 UUID(傳統GUID)的可能有一半,因為可用的隨機位少一個,變量消耗 3 bits。
一些偽隨機數發生器缺少必要的熵來產生足夠的偽隨機數。例如,使用偽隨機數生成器的 WinAPI GUID 生成器已被證明可生成遵循可預測模式的 UUID。 RFC 4122 建議「在各種主機上生成 UUID 的分布式應用程序必須願意依賴所有主機上的隨機數源。如果這不可行,則應使用名稱空間變體。」
碰撞編輯
當多次生成相同的 UUID 並將其分配給不同的指示對象時,就會發生衝突。對於使用來自網卡的唯一MAC地址的標準 版本1和2 的 UUID ,只有當實施與標準不同時,無論是無意還是故意,都可能發生衝突。
與 版本1 和 版本2 相比, UUID 使用隨機生成的節點 ID,基於散列的 版本3 和 版本5 的 UUID ,以及隨機 版本4 的 UUID ,即使沒有實現問題也可能發生衝突,儘管可能性很小,通常可能是忽略。可以基於對生日問題的分析來精確地計算該概率。
例如,至少碰撞一次具有50%的概率,根據 版本4 需要生成的 UUID 的數量是 ,計算如下:
這個數字相當於大約 85 年每秒產生 10 億個 UUID ,每個 UUID 16 bytes/字節,包含這麼多 UUID 的文件,大約 45 艾字節(EB),比目前存在的最大數據庫大很多倍,它們都在數百PB的數量級。
最小數必須查找碰撞要的概率來生成 版本4 的 UUID 的 p 由下式近似計算:
因此,在 103 萬億 個 版本4 UUID 中找到重複的概率是 (十億分之一)。
使用編輯
重要用途包括 ext2/ext3/ext4 文件系統用戶空間工具(e2fsprogs 使用 util-linux 提供的 libuuid),LUKS 加密分區,GNOME,KDE 和 Mac OS X,其中大部分源自 曹子德(Theodore Ts'o)的實現。
Solaris 中 UUID 的一種用途(使用Open Software Foundation實現)是識別正在運行的操作系統實例,以便在內核崩潰的情況下將故障轉儲數據與故障管理事件配對。
COM編輯
Microsoft的組件對象模型(COM)中使用了幾種GUID :
IID - 接口標識符;(在系統上註冊的那些存儲在Windows註冊表中)[HKEY_CLASSES_ROOT\Interface]
CLSID - 類標識符;(存儲在)[HKEY_CLASSES_ROOT\CLSID]
LIBID - 類型庫標識符;(存儲於)[HKEY_CLASSES_ROOT\TypeLib]
CATID - 類別標識符;(它在一個類中的存在將其識別為屬於某些類別類別)[HKEY_CLASSES_ROOT\Component Categories]
作為數據庫主鍵編輯
UUID 通常用作唯一鍵的數據庫表。
Microsoft SQL Server 版本4 中的 NEWID 函數 Transact-SQL 返回標準隨機 版本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 僅在應用程序中要求唯一性。
參考文獻編輯
參見編輯
- 全局唯一標識符(GUID)