本頁使用了標題或全文手工轉換

通用唯一辨識碼

維基百科,自由的百科全書
跳至導覽 跳至搜尋

通用唯一辨識碼(英語:Universally Unique Identifier,縮寫:UUID)是用於電腦體系中以辨識資訊的一個128位元識別碼。

根據標準方法生成,不依賴中央機構註冊分配,UUID具有唯一性,這與其他大多數編號方案不同。重複UUID碼概率接近零,可以忽略不計。

歷史[編輯]

1990年代, UUID 原本是用於阿波羅電腦網路計算系統(NCS),後被用於開放軟體基金會(OSF)的分散式計算環境(DCE)。DCE UUID的初始設計基於NCS UUID,其設計受 Domain/OS 中定義和使用的(64位元)唯一識別碼的啟發,這是一個也由 阿波羅電腦 設計的作業系統。後來,Microsoft Windows 平台採用 DCE 設計作為全域唯一識別碼(GUID)。

2005年7月,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是由一個16進位下的32位元數所構成,故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-426655440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

四位數字 M表示 UUID 版本,數字 N的一至三個最高有效位表示 UUID 變體。在例子中,M110 而且 Na10xx2),這意味著此 UUID 是「變體1」、「版本1」UUID;即基於時間的 DCE/RFC 4122 UUID。

規範的 `8-4-4-4-12` 格式字串基於 UUID 的16個位元組的「記錄布局」:

UUID 記錄結構
名稱 長度 (位元組) 長度(16進位數字碼長) 說明
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 的二進位編碼因系統而異。UUID的變體1完全以大端序(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或2或3位元。RFC 4122定義了4種變體:

  • 變體 0 (最顯著位為0,形如 0xxx2) 用於向下相容已經過時的1988年開發的 Apollo 網路計算系統(NCS)1.5 UUID 格式。 前6位元組是48位元時間戳(從1980年1月1日UTC開始的4微秒的滴答數),隨後2個位元組保留,再1個位元組是位址族(address family,使用了0..13個情形),最後7個位元組是主機ID。這類似於UUID的版本1.[1]
  • 變體 1 (形如10xx2),定義在RFC 4122/DCE 1.1 UUIDs, 或"Leach–Salz" UUID。它是按照大端序作為二進位儲存與傳輸。
  • 變體 2 (形如110x2),RFC稱「保留,微軟公司向下相容」。早期的Microsoft Windows平台的GUID使用該格式。它是按照小端序作為二進位儲存與傳輸。
  • 形如111x2 保留未使用。

目前,Microsoft guidgen 工具軟體產生變體1的結果。微軟文件[2]與RFC 4122稱GUID與UUID是同義詞。

版本[編輯]

對於「變體(variants)1」和「變體2」,標準中定義了五個版本(versions),並且在特定用例中每個版本可能比其他版本更合適。

版本由 M 字串中指示。

版本1 - UUID 是根據時間和 節點ID(通常是MAC位址)生成;

版本2 - UUID是根據識別碼(通常是組或使用者ID)、時間和節點ID生成;

版本3、版本5 - 確定性UUID 通過雜湊(hashing)命名空間(namespace)識別碼和名稱生成;

版本4 - UUID 使用隨機性偽隨機性生成。

Nil UUID[編輯]

Nil UUID是一個特例,值為 00000000-0000-0000-0000-000000000000 ;也就是說,所有位都設定為 0。

版本1(日期時間和MAC位址)[編輯]

版本1的UUID,是根據 60-bit 的時間戳 和 節點(生成UUID的電腦)的 48-bit MAC位址 而生成的。

時間戳的是這樣計算的。自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 僅在應用程式中要求唯一性。

參見[編輯]

參考文獻[編輯]

  1. ^ uuid.c. [2020-10-09]. (原始內容存檔於2021-02-24). 
  2. ^ Globally Unique Identifiers. Microsoft Developer Network. Microsoft. [2020-10-09]. (原始內容存檔於2019-02-13).