通用唯一识别码

通用唯一识别码

对于「变体(variants)1」和「变体2」,标准中定义了五个版本(versions),并且在特定用例中某些版本可能比其他版本更合适。

版本由字符串中的 M 指示。

版本1的UUID是根据时间和节点ID(通常是MAC地址)生成;版本2的UUID是根据标识符(通常是组或用户ID)、时间和节点ID生成;版本3、版本5透過對命名空间(namespace)标识符和名称進行雜湊生成確定性的UUID;版本4的UUID則使用随机性或伪随机性生成。

Nil UUID

编辑

Nil UUID是一个特例,值为 00000000-0000-0000-0000-000000000000 ;也就是说,所有位都设置为 0。

版本1(日期时间和MAC地址)

编辑

版本1的UUID,是根据 60-bit 的时间戳和节点(生成UUID的计算机)的48-bit MAC地址而生成的。

时间戳的是这样计算的:自公曆首次於天主教會和教皇國以外的地方使用的日期,也就是协调世界时(UTC)1582年10月15日午夜算起,每經過100納秒時間戳加1。RFC 4122声明时间值在公元3400年左右算術溢位[6]:3,取决于所使用的算法,代表此 60-bit 时间戳是有符号数量。但是,某些软件(如libuuid库)将时间戳视为无符号,把溢位時間推遲至公元5236年[9]。ITU-T Rec. X.667所定義的溢位時間為公元3603年[10]:v。

13-bit 或 14-bit「无统一」(uniquifying)时钟序列扩展了时间戳,以便处理处理器时钟不能足够快地前进的情况,或者每个节点有多个处理器和 UUID 生成器的情况。对于每个「版本1」UUID 对应于空间(节点)和时间(间隔和时钟序列)中的单个点,两个正确生成的「版本1」UUID 无意中相同的可能性实际上为零。由于时间和时钟序列总共74位,每个节点 id 可以生成

2

74

{\displaystyle 2^{74}}

1.8

×

10

22

{\displaystyle 1.8\times 10^{22}}

或 18 sextillion)個「版本1」UUID,每个节点 id 的最大平均速率为每秒 1630 亿[6]。

与其他 UUID 版本相比,基于来自网卡的 MAC 地址的「版本1」和「版本2」UUID,部分依赖于由中央注册机构发布的标识符,即由 IEEE 发布给网络设备制造商的 MAC 地址的组织唯一标识符(OUI)[11]。基于网卡MAC地址的「版本1」和「版本2」UUID 的唯一性还取决于网卡制造商正确地为其卡分配唯一的MAC地址,这与其他制造过程一样容易出错。此外,某些作業系統允許終端用戶自訂MAC地址,例如OpenWRT[12]。

使用节点的网络MAC地址作为节点ID,代表可以透過版本1的UUID逆向找到创建它的计算机。透過在檔案中嵌入UUID,可以實現追蹤到創建或修改這些檔案的計算機。在定位 Melissa 病毒的创建者时就使用了这个隐私漏洞[13]。

如果节点没有或不希望暴露MAC地址,RFC 4122 确实允许「版本1」(或2)UUID 中的 MAC 地址被随机的48位节点ID替换。在这种情况下,RFC要求节点ID的第一个八位字节的最低有效位应设置为1[6],这对应于MAC地址中的多播位,设置它是用于区分随机生成节点ID的UUID和基于来自网卡的MAC地址的UUID,网卡通常具有单播MAC地址[6]。

版本2(日期时间和MAC地址,DCE安全版本)

编辑

RFC 4122 保留了版本2的UUID用於“DCE security”;但並没有提供任何细节。因此,许多 UUID 实现省略了「版本2」。但是,「版本2」UUID 的规范由 DCE 1.1 身份验证和安全服务规范提供[4]。

「版本2」UUID 类似于「版本1」,除了时钟序列的最低有效8 bits 被“本地域(local domain)”号替换,并且时间戳的最低有效32 bits 由在指定本地域内有意义的整数标识符替换。在 POSIX 系统上,本地域号 0 和 1 分别用于用户 ID(UIDs)和组 ID(GIDs),其他本地域号用于站点定义[4]。在非 POSIX 系统上,所有本地域号都是站点定义的。

在 UUID 中包含 40 位元的域或标识符(domain/identifier)是有代價的。一方面,40 位元允许每个节点ID有大约1万亿个域或标识符的值。另一方面,由於时钟值被截断为28个最高有效位,有別於版本1中的60位元,版本2的UUID中的时钟也改成每429.49秒跳動(tick)一次,略多于7分钟,而不是版本1中的每100纳秒;并且,版本2的時鐘序列僅有6位元,版本1中則有14位元;每7分钟时钟周期内,每个节点、域或标识符只能生成64个唯一的UUID,而版本1的时钟序列值为16,384个[14]。因此,版本2可能不适合用于以节点、域或标识符在约7秒以上1次的速率下生成 UUID 的情况。

版本3和版本5(基于命名空间名称)

编辑

「版本3」和「版本5」的 UUID 透過雜湊(hashing)命名空间标识符和名称生成。版本3使用 MD5 作为散列算法,版本5則使用 SHA1[6]。

名称空间标识符本身就是一个 UUID。该规范提供了 UUID 用来表示命名空间为了统一资源定位符(URLs),完整域名、对象标识符和 X.500;但任何所需的UUID都可以用作命名空间指示符。

要确定与给定命名空间和名称对应的版本3的UUID,命名空间的 UUID 将转换为字节串,後面加上输入名称,然后用 MD5 进行散列,产生 128 位元。然后将六或七位替换为固定值,即 4 位元的版本號(例如“版本3”的 0011),以及 2 或 3 位元的 UUID 变体號(例如 10 代表RFC 4122的UUID,或 110 代表传统 Microsoft GUID)。由于预定了6到7位元,因此只有121或122位元用於維持 UUID 的唯一性。

版本5的UUID 和上面类似,但使用 SHA1 而不是 MD5。由于 SHA1 生成 160 位元的摘要,因此在替换版本號和变体號之前會把摘要截断为 128 位元。

版本3和版本5的UUID具有一個特性:相同名称空间和名称将映射到同一個UUID;然而,即使已知其中一項,也無法透過暴力搜索之外的方法從UUID逆向推導出另外一項。RFC 4122 推荐使用版本5(SHA1)而不是版本3(MD5),并建议不要使用任一版本的 UUID 作为安全凭证[6]。

版本4(随机)

编辑

版本4的UUID是隨機生成的。与其他 UUID 一样,其中4位元用于代表「版本4」,2到3位元代表变体號(102 或 1102 分别用于变体 1 和 2)。因此,对于变体1(即大多数 UUID),隨機生成的版本4的UUID會保留6位元用於表示变体號和版本號,其餘122位元用於隨機生成,故版本4变体1的UUID共计有

2

122

{\displaystyle 2^{122}}

5.3

×

10

36

{\displaystyle 5.3\times 10^{36}}

(5.3 undecillion)个。版本4变体2的UUID(传统GUID)則為變體1的一半,因为可用的随机位少一个,变量消耗 3 位元。

一些伪随机数发生器缺少必要的熵来产生足够的伪随机数。例如,使用伪随机数生成器的 WinAPI GUID 生成器已被证明可生成遵循可预测模式的 UUID。 RFC 4122 建议“在各种主机上生成 UUID 的分布式应用程序必须愿意依赖所有主机上的随机数源。如果这不可行,则应使用名称空间变体。”

相关推荐