跳到主要内容

UUID 解析实战:从一串字符读出版本、变体和时间戳

手里一串 UUID,怎么知道它是 v1 还是 v4?第 13 位读版本,v1 能解出时间戳和 MAC,v7 带 Unix 毫秒。本文讲清版本含义与本地排查源头的办法。

发布于 作者 李雷
#uuid #开发工具 #调试 #标识符

UUID 解析实战:从一串字符读出版本、变体和时间戳

排查线上问题时,我常常拿到一串孤零零的 UUID,比如 0190b5c2-3a40-7000-8000-000000000000,然后对着它发呆:这玩意儿是哪来的?能排序吗?里面藏着时间吗?其实这一串 36 个字符不是随机字母汤,它的每一位都有约定。只要会读,你不查数据库也能知道它是几版、走哪种字节序布局、甚至是什么时候生成的。

先记住一个位置:第 13 位是版本号

UUID 标准形态是 8-4-4-4-12 分段。最关键的一点:第 13 个十六进制字符,也就是第三段的第一位,就是版本号。它不是整串的第一个字符,这是很多人第一次踩的坑,因为 v7 开头几个字节是变化的时间戳,看着没规律。

举个真实例子。把 0190b5c2-3a40-7000-8000-000000000000 拆开,第三段是 7000,第一位是 7,所以它是 v7。再看 0190ae99-a800-4000-8000-000000000000,第三段 4000 的第一位是 4,那就是 v4。同一个位置读到 1、3、5,就分别是 v1、v3、v5。记住这一位,大半工作就完成了。

版本各自意味着什么

知道是几版还不够,得知道每版能给你什么:

  • v1:基于时间和机器节点。它藏着从 1582-10-15 起算的 60 位百纳秒计数,还有 48 位节点(历史上就是网卡 MAC 地址)。这意味着 v1 会泄露生成时间和生成机器。
  • v4:纯随机。除了版本位和变体位被固定,其余 122 位都来自密码学随机源。它能告诉你的几乎只有「它是随机的」,没有时间、没有机器、没有计数器。
  • v3 / v5:基于命名空间的哈希(v3 用 MD5,v5 用 SHA-1)。同样的输入永远得到同一个 UUID,但反推不出原文,也没有生成时间。
  • v7:时间有序。开头 6 个字节是 48 位 Unix 毫秒时间戳,所以它天生可按时间排序,做数据库主键时对 B 树索引友好。

如果你正在选生成方案,可以直接用 UUID 生成器 对照着看不同版本长什么样,需要时序键就用 v7。

变体位:别把它当版本

紧挨着版本之后还有一个容易混淆的概念:变体。第 17 个十六进制字符(第四段第一位)是变体位,它描述的是字节序家族,不是生成算法。那里读到 8、9、a、b,是 RFC 4122/9562 变体;c 或 d 是微软 GUID 布局;0 到 7 是早期的 NCS 布局。

为什么要单独看它?因为一个从 .NET 服务漏过来、走小端字节序的微软 GUID,版本位可能看着正常,但字节序不一样,直接当 RFC UUID 解析就会错位。变体检查能逮住这种少见但折磨人的情况。注意:v4 和 v7 可以是同一个变体,真正区分它们的永远是版本位。

能不能还原生成时间

只有 v1 和 v7 能。我自己最常用这一招来排查「这条记录到底什么时候建的」:一条日志只用 UUID 引用某条记录,我不想为了一个时间去翻数据库,就直接把 UUID 拆开读。

经典例子 c232ab00-9414-11ec-b3c8-9e6bdeced846,第三段第一位是 1,是 v1。把它那 60 位百纳秒计数换算过来,得到 2022-02-22T19:22:22Z,同时还能解出 14 位时钟序列和 48 位节点。v7 则更直接,头 6 个字节就是 Unix 毫秒,解成 UTC 和本地时间即可。而 v4 是随机、v5 是哈希,这两类没有可还原的时间,工具会如实告诉你「无」,不会瞎猜。

如果你拿到的是 v7 或 v1 的毫秒/百纳秒数值,想再换成可读日期,可以接着用 时间戳转换器 做一次校验。

两个哨兵值

还有两个特殊值得认识。Nil UUID 全是零 00000000-0000-0000-0000-000000000000,像别处用 null 那样当空占位。Max UUID 在十六进制下全是 1 ffffffff-ffff-ffff-ffff-ffffffffffff,RFC 9562 把它定义为最大值,做范围扫描时当上界很方便。两者都合法,但没有版本和变体含义,看到它们别费劲去解版本。

本地解析,不上传

这类排查我坚持在本地做。版本与变体解码、v1 和 v7 的时间戳换算、十六进制字段拆解,全是浏览器里跑的纯 JavaScript,粘进去的 UUID 不离开页面。要动手实操,直接打开 UUID 检查器,粘一串进去,版本、变体、时间戳、逐段字段会一次性铺开。比起对着 RFC 9562 啃文字,看一眼真实拆解,你会立刻明白为什么是第 13 个字符决定一切。

下次再收到一串来历不明的 UUID,先看第 13 位,再看第 17 位,该排序排序,该追时间追时间。


Made by Toolora · Updated 2026-06-13