TOC

UUID

Universally Unique Identifier 通用唯一识别码

是 ISO/IEC 标准,也定义在 IETF 的 RFC4122 中。

128 位,也就是 16 字节,通常使用 32 位 16 进制数字,以 8-4-4-4-12 的形式表示,例如:d09abf7e-3e39-11ec-9dbc-b1755772e461

历史

  1. 阿波罗电脑公司 Apollo 的网络计算系统 NCS
  2. 开放软件基金会 OSF 的 DCE 系统(分布式计算环境)
  3. 微软 GUID 采用 DEC 的设计
  4. 互联网工程任务组 IETF 发布 RFC 4122,
    同时,国际标准化组织 ISO 和国际电信联盟 ITU 也对其进行了标准化。

语法

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

M 表示版本,N 的一到三个最高有效位表示变体类型。

变体

  • 变体 0: 0 (0 - 7) 早期,Apollo 网络计算系统使用的版本。
    6 字节时间戳,2 字节保留,1 字节地址族,7 字节主机 ID
    时间戳是从 1980 开始的四位微秒格式
    由于最早的设计地址族只定义了 0 - 13,标准化之后,用最高位是不是 0 来区分
  • 变体 1: 10 (8 - b) 这就是标准所采用的风格
  • 变体 2: 110 (c, d) 微软 GUID,和变体 1 唯一的区别就是从大端序变成小端序
    PS: 事实上,微软 GUID 后来也改成变体 1 了
  • 变体 3: 111 (e, f) 保留

PS: 后面都当成是变体 1。

版本

  • Nil UUID,一个特例:00000000-0000-0000-0000-000000000000

  • UUID1 48bit Mac 地址 + 60bit 时间戳
    布局:

    • 时间戳低位 32bits
    • 时间戳中间 16bits
    • 4bits 版本 + 时间戳高位 12bits
    • 2bits 变体类型 + 14bits 随机数
    • 机器 ID 48bits

    时间戳的计算方法:从公历开始采用的时间 1582-10-15 00:00:00 开始,以 100 纳秒(0.1 微秒)作为间隔。Python UUID 标准库关于这一部分的实现:

    nanoseconds = time.time_ns()
    # 0x01b21dd213814000 is the number of 100-ns intervals between the
    # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
    timestamp = nanoseconds // 100 + 0x01b21dd213814000
    
  • UUID2
    定义在 DCE, RFC4122 保留了这一部分,但是没有包含实现细节
    > “版本 2” UUID 类似于“版本 1”,除了时钟序列的最低有效 8 bits 被“本地域(local domain)”号替换,并且时间戳的最低有效 32 bits 由在指定本地域内有意义的整数标识符替换。在 POSIX 系统上,本地域号 0 和 1 分别用于用户 ID(UIDs)和组 ID(GIDs),其他本地域号用于站点定义。在非 POSIX 系统上,所有本地域号都是站点定义的。

  • UUID3 命名空间 + 名称
    命名空间是一个 UUID
    MD5(命名空间 + 名称), 然后替换版本和变体类型相关的位
    UUID3 定义了以下几个命名空间:
    1. 统一资源定位符 URL
      6ba7b811-9dad-11d1-80b4-00c04fd430c8
    2. 域名
      6ba7b810-9dad-11d1-80b4-00c04fd430c8
    3. 对象标识符
      6ba7b812-9dad-11d1-80b4-00c04fd430c8
    4. X.500 轻型目录访问协议 LDAP
      6ba7b814-9dad-11d1-80b4-00c04fd430c8
  • UUID4 随机 UUID,除了版本和变体类型信息
    • 因此,第 14 位一定为 4,第 19 位一定为 89ab 中的一个(10xx)
  • UUID5 和 UUID3 类似,不过 MD5 换成 SHA1