← 返回博客

UUID v5 命名空间详解

2026-04-13 · 5 分钟阅读

UUID v5 的工作原理

UUID v5 是一种"确定性 UUID":给定相同的命名空间(namespace)和名称(name),总是产生完全相同的 UUID。其生成过程:将命名空间 UUID(16 字节)和名称(任意字节序列)拼接;对拼接结果计算 SHA-1 哈希(160 位);取前 128 位,设置版本字段为 5,设置变体字段为 RFC 4122;得到最终的 UUID v5。UUID v5 的本质是一个特定格式的 SHA-1 哈希,因此它的"唯一性"依赖于命名空间的选取和 SHA-1 的抗碰撞性。

标准命名空间

RFC 4122 预定义了 4 个标准命名空间,用于为不同类型的名称生成 UUID:

也可以自定义命名空间:使用任意一个 UUID v4(随机生成)作为你的应用或服务的私有命名空间 UUID,不同的应用使用不同的命名空间,即使名称相同也会产生不同的 UUID。

UUID v5 的实际应用场景

UUID v5 的核心价值在于"幂等性"——相同输入总产生相同 ID。常见应用场景:内容寻址存储(为同一文档的 URL 生成稳定 UUID,方便去重);数据同步(从外部系统同步数据时,用外部 ID 生成 UUID,保证幂等性);测试数据(生成可重现的测试 UUID,使测试稳定可重复);配置文件(为配置项生成确定性 UUID,不依赖数据库自增 ID);事件溯源(为特定事件类型和参数生成确定性事件 ID)。

多语言代码示例

# Python
import uuid

# 使用标准命名空间
dns_uuid = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')
url_uuid = uuid.uuid5(uuid.NAMESPACE_URL, 'https://example.com/page')
print(dns_uuid)  # 总是:cfbff0d1-9375-5685-968c-48ce8b15ae17

# 自定义命名空间(先生成一个固定的 v4 作为命名空间)
MY_APP_NAMESPACE = uuid.UUID('12345678-1234-5678-1234-567812345678')
user_id = uuid.uuid5(MY_APP_NAMESPACE, '[email protected]')
print(user_id)  # 对于相同邮箱总是产生相同 UUID

# JavaScript (uuid 包)
import { v5 as uuidv5, v4 as uuidv4 } from 'uuid';

const DNS_NAMESPACE = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
const id = uuidv5('example.com', DNS_NAMESPACE);
console.log(id); // cfbff0d1-9375-5685-968c-48ce8b15ae17

// 自定义命名空间
const MY_NAMESPACE = uuidv4(); // 应用启动时生成一次并保存
const userId = uuidv5('[email protected]', MY_NAMESPACE);

// Go
import (
    "github.com/google/uuid"
    "fmt"
)
id := uuid.NewSHA1(uuid.NamespaceDNS, []byte("example.com"))
fmt.Println(id)

UUID v3 vs v5:如何选择

UUID v3 和 v5 的区别仅在于哈希算法:v3 使用 MD5,v5 使用 SHA-1。功能上完全相同,都是确定性命名空间 UUID。选择建议:优先使用 v5(SHA-1),因为 MD5 在密码学上已被认为不安全(虽然这里只是用于生成确定性 ID,而非安全用途,但统一使用更安全的算法是好习惯);如果旧系统已经在使用 v3 且需要保持兼容,继续使用 v3;如果两个系统需要生成相同的 UUID(互操作),必须使用相同的版本(v3 或 v5)和相同的命名空间。

设计应用私有命名空间的最佳实践

为应用设计私有命名空间时的建议:每个应用或服务使用一个固定的随机 UUID v4 作为命名空间,在配置文件或代码常量中硬编码(不要每次运行都随机生成);不同的实体类型(用户、文章、订单)使用不同的子命名空间(可以用 v5 派生:在主命名空间内派生"users"命名空间,再在"users"命名空间内派生每个用户的 UUID);命名空间 UUID 应该是应用的秘密配置,不要在日志中输出或在 API 中暴露;文档记录你的命名空间 UUID 和每种实体类型的命名约定,方便团队成员复现相同的 UUID。

立即免费使用相关工具

免费使用 →