通用唯一识别码

admin 5286次浏览

摘要:对于“变体(variants)1”和“变体2”,标准中定义了五个版本(versions),并且在特定用例中某些版本可能比其他版本更合适。 版本由字符串中

对于“变体(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 的分布式应用程序必须愿意依赖所有主机上的随机数源。如果这不可行,则应使用名称空间变体。”

相关文章
友情链接