一次生成 1 到 500 个符合 RFC 4122 v4 的 UUID,支持标准连字符格式、全大写、以及 32 位无连字符格式。随机数取自浏览器的密码学随机源,不上传任何内容,也不会出现"从某个 ID 能推出另一个"的情况。

v4 UUID 到底是什么

UUID 是一个 128 位的数,写成 32 个十六进制字符、按 8-4-4-4-12 分五组。这个排布不是为了好看——它里面编码了两个字段,让这个值能自我描述。

第三组的第一个字符是**版本号**,v4 永远是 4。第四组的第一个字符编码**变体**,永远是 8、9、a、b 之一。这 6 个 bit 被格式占死,剩下 122 个 bit 才是真正的随机位。

定义就这么多。v4 UUID 里没有时间戳、没有机器标识、没有序列号。同一台机器同一毫秒生成的两个 UUID 毫无关系——唯一可能把它们联系起来的只有概率。

也正因为版本位和变体位是固定的,v4 UUID **不是**均匀随机的 128 位字符串。如果你需要每一位都随机,请直接生成 16 个随机字节再转十六进制,不要用 UUID。

重复的概率有多大

122 个随机位对应约 5.3 × 10^36 种可能的 v4 UUID。按生日悖论,碰撞概率达到一半需要生成约 2.7 × 10^18 个值。

换个说法:每秒生成十亿个 UUID,要连续生成约 85 年,出现重复的概率才到 50%。对你我可能写的任何系统来说,把 v4 UUID 当唯一值用是安全的。

真正该担心的不是碰撞,而是另一种"重复":复制数据行、重跑初始化脚本、还原数据库快照,都可能造出两条 UUID 相同的记录。那是数据问题,不是随机性问题,任何生成器都保护不了你。

怎么生成 UUID

  1. 设置生成数量一次 1 到 500 个,每一个都独立生成。
  2. 选择是否带连字符保留连字符得到标准的 36 位格式;去掉则是 32 位连续十六进制字符串。
  3. 选择大小写规范里小写是标准形式;SQL Server 生态里通常用大写。
  4. 复制或下载整批可一键复制,也可下载成文本文件,一行一个 UUID。

三种输出格式

三种格式承载的是同一组 128 位数据。互相转换只靠改大小写和增删连字符,绝不能重新生成。
格式长度在哪里见到
小写 + 连字符36 个字符标准形式。PostgreSQL、MySQL、Python、Java 和绝大多数 API 默认都是它。
大写 + 连字符36 个字符SQL Server 与 SSMS 这样显示 GUID;C# / .NET 也常规范化为大写。
无连字符32 个字符打包进 16 字节的二进制列,以及任何"连字符纯属浪费字节"的场合。

UUID 和 GUID 是一回事吗

是一回事。GUID(globally unique identifier)是微软对同一个 128 位格式的叫法。SQL Server、C#、COM 里的 "GUID" 和 PostgreSQL、Python、REST API 里的 "UUID" 可以直接互通,除了大小写和连字符之外不需要任何转换。

这个格式在三处标准里定义且互相一致:RFC 4122 及其 2024 年的替代版 RFC 9562、ISO/IEC 9834-8、ITU-T X.667。所以叫哪个词,只取决于你在读哪个生态的文档。

为什么随机 UUID 不适合当数据库主键

这是大家对 v4 UUID 误解最深、代价也最大的地方,而且跟碰撞概率毫无关系。

聚簇索引——MySQL InnoDB 的默认行为,SQL Server 里主键也会变成它——按主键顺序存放数据行。自增整数键总是追加到索引末尾,代价很低;随机键每次都插到随机位置,引擎不得不分裂页、搬移数据、在磁盘上散乱写入。写入吞吐下降,索引碎片化。

还有第二笔开销:128 位而不是 32 或 64 位。每个二级索引都会带上主键的副本,所以这个代价要乘以表上的索引数量。在大表上,这是以 GB 计的量。

三条出路,按改动量从小到大。第一,主键仍用自增整数,UUID 另存一列并单独建索引,供外部引用——最常用的折中。第二,改用时间有序的 UUID 版本。第三,在 PostgreSQL 上接受存储开销,直接用原生 uuid 类型,它按 16 字节存储,而不是文本形式的 36 字节。

时间有序这条老路是 v1,但它会泄露机器的 MAC 地址和生成时间。2024 年 5 月发布的 RFC 9562 给出了更好的答案:**v7** 把 48 位毫秒时间戳放在最前面,其余填随机数,既有可排序性又不暴露 MAC 地址。**v6** 是同样的思路,只是把时间戳字段重排以便按字典序排序。

如果你的数据库支持,今天做主键通常该默认用 v7;而 v4 仍然适合那些纯粹作为不透明标识、从不参与排序的场景。

UUID 不是什么

它不是密钥。v4 UUID 在实践中猜不到,但它不是带密钥或带认证的值:谁知道了它就是知道了,无法吊销、无法轮换。不要拿它当 API key、密码重置令牌或会话 ID——那些要用专门的、带密钥的生成器。

它不是哈希。同样的输入生成出同样的 UUID 在设计上就不可能,所以它没法用来判重或给内容做指纹。

它不保证唯一。它是一个碰撞概率可忽略的**概率性**标识符,这和数据库约束不是一回事。如果两行数据绝不能共用同一个标识符,请用唯一索引来保证,而不是靠概率。

它不携带任何语义。你无法从 v4 UUID 里取出创建时间、租户或分片信息。如果确实需要这些,请显式编码进 v8 UUID,或者干脆放在单独的列里,好让它们可被查询。

参考资料

常见问题

这些 UUID 真的不会重复吗?
v4 UUID 含 122 个随机位,即使生成数十亿个,重复的概率也可以忽略。
UUID 和 GUID 有什么区别?
没有区别,是同一个东西。GUID 是微软对同一种 128 位标识符格式的叫法。
能生成不带连字符的 UUID 吗?
可以。取消勾选连字符选项,就得到 32 位连续字符串。
📢 [AD_SLOT] · 728x90 Responsive Display
已复制到剪贴板!