UUID.randomUUID() 生成的是严格符合 RFC 4122 的版本 4 UUID:版本位固定为 4,变体位强制为 10xx(即第 19 位字符为 8/9/a/b),122 位来自 SecureRandom,toString() 输出 8-4-4-4-12 标准格式。

UUID.randomUUID() 生成的就是符合 RFC 4122 标准的版本 4 UUID,无需额外处理。
它默认输出的是 128 位、基于伪随机数的 UUID,结构为 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx(其中 y 是 8、9、a 或 b),完全满足 RFC 4122 对 version 4 和 variant 2 的定义。
为什么 UUID.randomUUID() 天然合规
Java 的 UUID.randomUUID() 不是“近似合规”,而是严格按 RFC 4122 实现:
- 版本位(第 13 个 hex 字符)固定为
4,表示 version 4 - 变体位(第 19 个 hex 字符的高 2 位)强制设为
10xx,即只取8、9、a、b,符合 variant 2(RFC 定义的“Leach-Salz”变体) - 其余 122 位来自
SecureRandom(JDK 17+ 默认用DRBG),具备密码学强度的随机性 - 生成结果可直接用于 HTTP header、数据库主键、分布式 trace ID 等需要标准 UUID 的场景
toString() 输出就是标准格式,别手动拼接
调用 UUID.randomUUID().toString() 返回的是带连字符的 36 字符字符串(如 550e8400-e29b-41d4-a716-446655440000),这正是 RFC 4122 规定的文本表示法。
常见错误是自己拼字符串:
String bad = uuid.getMostSignificantBits() + "-" + uuid.getLeastSignificantBits(); // ❌ 错误:不是十六进制,也不带前导零,不合规
正确做法只用 toString() 或 uuid.toString():
UUID id = UUID.randomUUID(); String standard = id.toString(); // ✅ 自动格式化为 8-4-4-4-12
去掉连字符后还是 RFC 合规的 UUID 吗?
去掉连字符(如用 id.toString().replace("-", ""))得到的是 32 字符十六进制串,语义上仍是同一个 UUID,但不再符合 RFC 4122 的文本表示规范。
是否可用,取决于下游系统是否接受紧凑格式:
- PostgreSQL 的
UUID类型支持带/不带连字符输入 - MySQL 的
BINARY(16)存储通常先用UNHEX()转 32 字符,此时连字符必须先删掉 - OpenAPI/Swagger 文档中若字段类型声明为
string+format: uuid,则要求必须含连字符,否则校验失败 - gRPC/Protobuf 的
google.api.field_behavior注解也隐式依赖标准格式
所以:存储或传输时可去横杠,但对外暴露(API 响应、日志、文档)建议保留 toString() 原始格式。
关键点在于:UUID.randomUUID() 本身没问题,问题常出在后续字符串操作或格式误判。真正容易被忽略的,是把「UUID 值」和「UUID 的文本表示」混为一谈——前者是 128 位二进制,后者只是其中一种人类可读编码。










