跳到主要内容

UUID v5 是什么:用命名空间和名称生成确定性 ID

讲清 UUID v5 如何用 SHA-1 把命名空间加名称变成确定性 ID,和 v4 随机的根本区别,以及怎样用它从 URL、邮箱、域名生成稳定不变的标识符。

发布于 作者 李雷
#uuid #uuid-v5 #确定性ID #命名空间 #后端开发

UUID v5 是什么:用命名空间和名称生成确定性 ID

大多数人第一次接触 UUID,用的都是 v4。调一次函数,拿到一串随机字符,贴进数据库主键,完事。但当我开始处理「同一份数据从两个来源进系统」这类问题时,v4 的随机性就成了麻烦:两边各生成各的随机 ID,合并时永远对不上。这时候真正派上用场的,是 v5。

v5 的核心:从输入算出 ID,而不是凭空发一个

UUID v5 不掷骰子。它接受两样东西,一个命名空间(一个固定的 UUID)和一个名称(任意字符串),把命名空间的 16 个原始字节和名称的 UTF-8 字节拼起来,用 SHA-1 哈希,截取前 16 字节,再打上版本 5 的位和 RFC 变体位。整个过程没有时钟,没有随机数。这意味着同样的命名空间加同样的名称,在任何机器、任何编程语言里,永远算出同一个 UUID。

这套规则不是哪个库自己发明的。RFC 4122(以及后来的 RFC 9562)明文规定了 v5 用 SHA-1,所以任何合规实现算出的值都一模一样。你可以直接在 /zh/t/uuid-v5-generator/ 里验证这一点。

和 v4 到底差在哪

v4 是纯随机:每次调用都给一个全新且不可预测的 ID,和输入毫无关系,所以你永远无法复现某一个。它适合会话令牌、临时密钥这种「需要唯一且别人猜不到」的场景。

v5 是确定性的:输入决定输出,可以反复重算。它适合「需要从已有数据派生出稳定 ID」的场景。一个简单判断标准是,如果你将来还想凭原始数据把这个 ID 算回来,就用 v5;如果你只想要一个谁都猜不到的随机值,就用 v4。

要补充一句:正因为 v5 只是对公开输入做哈希,任何知道你命名空间和命名规则的人都能把每个 ID 重新算出来。这对可复现是优点,但千万别把 v5 UUID 当秘密令牌用。

命名空间:为什么不能只哈希名称

命名空间是一个固定的 UUID,用来给名称划定范围。如果只对名称哈希,DNS 主机 example.com 和某个恰好也叫 example.com 的商品编号就会撞成同一个 ID。各自配上自己的命名空间,两者就能干净地分开。

RFC 4122 在附录 C 里定义了四个常用命名空间,直接拿来用即可:

  • DNS:6ba7b810-9dad-11d1-80b4-00c04fd430c8,用于完全限定域名
  • URL:6ba7b811-...,用于网址
  • OID:6ba7b812-...
  • X.500:6ba7b814-...

如果这四个都不贴合你的数据,随便生成一个随机 UUID,把它当作一整组 ID 的私有命名空间反复使用就行。

一个能自己动手验证的例子

最能说明确定性的,是一个固定输入输出。在 DNS 命名空间 6ba7b810-9dad-11d1-80b4-00c04fd430c8 下,对名称 example.com 求 v5,结果永远是:

cfbff0d1-9375-5685-968c-48ce8b15ae17

不管你今天算还是明年算,在你的电脑上算还是同事的电脑上算,用 Python 算还是 Go 算,都是这一串。你可以把这个例子贴进生成器自己跑一遍,确认无误。这也是 v5 适合做内容寻址键的根本原因:ID 随时能从数据重算出来,不必把一个随机值存进映射表。

几个真实用途

我自己用得最顺手的几个场景:

第一,给配置实体一个不靠数据库的稳定 ID。有一份以域名为键的集成清单,把每个域名在 DNS 命名空间里哈希,用得到的 v5 UUID 作主键。一年后重新导入同一份配置,每行都保留原来的 ID,因为 ID 是域名的纯函数。

第二,给两个来源的记录去重。同一个用户既在 CRM 导出里又在计费数据里,两边都只有邮箱。两边都算 uuidV5(邮箱, 你的命名空间),两行就归到同一个 ID,做 join 或 upsert 直接合并,不用模糊匹配。

第三,缓存或 CDN 的内容寻址路径。用 URL 命名空间从文档的规范 URL 派生键,任何知道这个 URL 的服务都能算出一模一样的 v5 UUID 找到条目,worker 之间不用协调。

有一个坑要提醒:v5 哈希的是名称的 UTF-8 字节,名称若被编成 UTF-16 或带了多余空白,算出的 UUID 就和另一个系统算的对不上。各处都要把名称规范化并去掉首尾空白,确保字节完全相同。

它在 ID 家族里的位置

v5 解决的是「确定性派生」这一类问题。如果你的需求其实是「时间有序的随机 ID」,那 v5 就不对路,可以看看时间排序的 /zh/t/uuid-v7-generator/。把这两类摆在一起,选型会清楚很多:要可复现选 v5,要随机有序选 v7。


Made by Toolora · Updated 2026-06-13