它如何工作
随机源是 crypto.getRandomValues(),与浏览器生成会话密钥用的是同一个加密级随机数发生器,不是 Math.random()。这样得到的 v4 不可预测,适合做不可猜测的标识符。
格式化时把版本位(第 7 个十六进制位固定为 4)和变体位(第 9 个十六进制位固定为 8/9/a/b)写死,这是 RFC 4122 的硬性要求——少了这两步,得到的只是「长得像 UUID 的随机串」,很多数据库与校验库会拒收。
v7 的前 48 位是毫秒级 Unix 时间戳,其余为随机位,因此按字典序排序即近似按时间排序,对 B+ 树主键非常友好,能显著减少随机写入带来的页分裂。同一毫秒内生成的多个 UUID 由计数器保证递增。
v4 与 v7 怎么选
| 对比项 | UUID v4 | UUID v7 |
|---|---|---|
| 结构 | 122 位全随机 | 48 位时间戳 + 74 位随机 |
| 有序性 | 无序 | 按时间有序 |
| 数据库主键 | 随机写入,索引易碎片化 | 顺序写入,索引友好 |
| 是否泄露时间 | 不泄露 | 可从 ID 推出生成时间 |
| 适用 | 对外暴露的不可猜 ID、会话 token | 内部主键、日志 ID、事件 ID |
若 ID 会暴露给外部且生成时间属于敏感信息,优先 v4;若纯粹用作数据库主键且写入量大,优先 v7。
常见问题
生成的 UUID 会重复吗?
v4 的碰撞概率极低:需要生成约 2.7×10¹⁸ 个才有 50% 概率出现一次碰撞。实践中可以忽略,但数据库层面仍建议保留唯一索引。
结果会被记录或上传吗?
不会。页面没有网络请求,也不写 Cookie 或 localStorage,刷新即消失。你可以打开开发者工具的网络面板验证。
为什么有的库说我的 UUID 不合法?
多半是版本位或变体位不对。手写的随机串常常只是「32 位十六进制」,缺少第 13 位固定为 4、第 17 位为 8/9/a/b 的约束。用本工具生成的一定符合 RFC 4122 / RFC 9562。