Skip to content

免费 ULID 生成器 — 生成并解码 ULID

在线生成、解码并转换 ULID——免费且 100% 在浏览器中运行。从任意 ULID 提取内嵌时间戳,在 ULID 与 UUID 间互转,支持批量生成与单调递增模式。任何数据都不会发往服务器。

无追踪 浏览器中运行 免费
每个 ULID 都用你浏览器的密码学 RNG(crypto.getRandomValues)在本地生成。任何内容都不会被上传、记录或存储。

每个 ULID 使用全新的 80-bit 随机数。

什么是 ULID?

ULID——通用唯一、按字典序可排序的标识符(Universally Unique Lexicographically Sortable Identifier)——是一个 128-bit 标识符,它的诞生是为了修复随机 UUIDv4 的一个实际短板,同时保留其最佳特性:你可以在任何地方生成一个、无需中央协调者,并确信它是唯一的。区别在于 ULID 可按时间排序。它呈现为 26 个字符的 Crockford Base32,分为两部分:前 10 个字符是自 Unix 纪元起以毫秒计的 48-bit 时间戳,后 16 个字符是 80-bit 密码学安全的随机数。把时间放在前面、用一个保序的字母表编码,标识符作为普通字符串便会按时间顺序排序。

这一个设计选择对数据库有着超乎寻常的影响。随机的 UUIDv4 主键在每次插入时都会落到 B-tree 索引中一个不可预测的位置,导致索引碎片化、缓存抖动,并随着表的增长缓慢拖垮写入性能。而 ULID 因为带时间前缀,每次都落在索引末尾或附近——插入保持顺序、索引保持紧凑,针对时间窗口的范围扫描也变得低廉。你既获得了 UUID 那种无需协调的生成方式,又获得了自增整数般的插入局部性,而无需暴露一个可被猜测的顺序计数器。

编码细节是刻意为之的。Crockford Base32 去掉了字母 I、L、O、U,既为避免与数字 1 和 0 的视觉混淆,也为让字符串在输入时大小写不敏感。结果是 26 个不带连字符的字符,可安全地放进 URL、文件名或请求头而无需转义——明显比 UUID 那 36 个字符的带连字符形式更短。48-bit 时间戳在很长一段时间内都不会耗尽:在毫秒计数器溢出之前,它可以表示直到 10889 年的日期。

ULID 并非万能。内嵌的时间戳会暴露记录的创建时间,这对调试和排序是个特性,但若你不希望暴露它,便是个小小的信息泄露。而且如果你的技术栈坚定地使用 UUID 类型,你或许更偏好 UUIDv7——它在标准 UUID 格式内应用了同样的时间前缀思路。但当你想要既短、又 URL 安全、又可排序的标识符,能在任意节点铸造、并能从中读回一个时间戳时,ULID 是一个绝佳的默认选择——而且因为它只是 128-bit,你随时可以用本工具的 Convert 标签页在它与 UUID 之间相互转换。

// Browser / Node with the `ulid` package
import { ulid, decodeTime } from 'ulid';

const id = ulid();          // e.g. 01KVT0F720ZK9N4T2QX7VR8WMC
const ts = decodeTime(id);  // 1782210600000  ->  2026-06-23T10:30:00.000Z

// Monotonic factory: strictly increasing within the same millisecond
import { monotonicFactory } from 'ulid';
const next = monotonicFactory();
next(1782210600000); // 01KVT0F720ZK9N4T2QX7VR8WMC
next(1782210600000); // 01KVT0F720ZK9N4T2QX7VR8WMD
next(1782210600000); // 01KVT0F720ZK9N4T2QX7VR8WME

核心功能

一页内生成、解码、转换

三个标签页覆盖整个 ULID 工作流:铸造新 ULID、解码已有 ULID 以读取时间戳、在 ULID 与 UUID 之间无损转换。多数同类工具只做第一项;这里的完整往返都集中在同一个页面上。

时间戳解码器

粘贴任意 ULID,读出它被创建的确切毫秒——以 UTC、以你的本地时间、以及以原始 Unix 毫秒呈现——外加 80-bit 的随机段。无需任何数据库查询即可审计标识符何时被铸造。

无损的 ULID ↔ UUID 转换

ULID 和 UUID 都是 128-bit,因此转换精确且可逆。Convert 标签页会自动识别你粘贴的是哪种格式并产出另一种,让你在可排序的 ULID 与 UUID 类型的列或 API 之间架桥,而不损失一个比特。

单调递增模式

需要让同一毫秒内创建的 ID 也严格有序?单调递增模式会把随机数加一,确保每个 ULID 都大于上一个,让紧凑的插入循环保持完美有序。

批量生成

一次创建多达 50 个 ULID,并用 Copy All 复制整套。非常适合为测试夹具播种、批量插入,或填充查找表,而不必点击五十次。

自定义时间戳

内嵌一个特定时刻而非当前时间——在生成确定性的测试数据,或在迁移中回填记录、同时保持可排序特性时很有用。

密码学安全的随机性

那 80 个随机位来自 crypto.getRandomValues,即浏览器的 CSPRNG——绝不用 Math.random——因此每个 ULID 都不可预测,同一毫秒内的碰撞概率微乎其微。

100% 私密,仅在浏览器中运行

每个 ULID 都完全在你的设备上生成、解码和转换。没有网络请求、没有日志、没有存储——你可以在开发者工具 → Network 中亲自验证。标识符绝不会抵达任何第三方。

ULID 示例

生成单个 ULID

Mode: Standard · Quantity: 1
01KVT0F720ZK9N4T2QX7VR8WMC

一个 ULID 是 26 个字符的 Crockford Base32。前 10 个字符编码一个 48-bit 毫秒时间戳,后 16 个字符编码 80-bit 密码学安全的随机数,取自 crypto.getRandomValues。由于时间戳在前、且 Base32 保持字节序,晚生成的 ULID 作为普通字符串排序时总是排在更早生成的之后——无需另建索引。点击 Copy 抓取该值;再次点击 Generate 获取一个新值。

解码 ULID 以读取其时间戳

01ARYZ6S41TSV4RRFFQ69G5FAV
Timestamp (UTC): 2016-07-30T22:36:16.385Z · Randomness: TSV4RRFFQ69G5FAV

解码会把前 10 个字符还原回创建时内嵌的 48-bit 毫秒值——这里是 1469918176385 毫秒,即 2016-07-30T22:36:16.385Z。这是 ULID 规范中的标准示例。Decode 标签页会以 UTC 和你的本地时间显示该时间戳、原始 Unix 毫秒值,以及 80-bit 的随机段,让你无需查询数据库即可精确审计某个标识符是何时铸造的。

将 ULID 转换为 UUID

01KVT0F720ZK9N4T2QX7VR8WMC
019ef407-9c40-fcd3-5268-57e9f784728c

ULID 和 UUID 都恰好是 128-bit,因此转换无损且完全可逆——同样的位仅仅是从 Crockford Base32 重新编码为带连字符的十六进制。Convert 标签页会自动识别你粘贴的是 ULID 还是 UUID,并转换成另一种形式。这让你能把 ULID 存进 UUID 列,或把 ULID 交给只认 UUID 的系统,等需要可排序字符串时再转回来。

批量生成单调递增的 ULID

Mode: Monotonic · Quantity: 3 (same millisecond)
01KVT0F720ZK9N4T2QX7VR8WMC
01KVT0F720ZK9N4T2QX7VR8WMD
01KVT0F720ZK9N4T2QX7VR8WME

当许多 ID 在同一毫秒内创建时,普通 ULID 共享 10 个字符的时间前缀,但它们的随机尾段是无序的。单调递增模式修复了这一点:在同一毫秒内,它会把前一个随机值加一,使每个 ULID 都严格大于上一个,整批保持完美有序。注意这三个值仅在末位字符上不同(C、D、E)——非常适合高吞吐插入场景,即便在亚毫秒速率下也必须维持顺序。

为指定日期生成 ULID

Custom time: 2026-06-23 10:30:00 UTC
01KVT0F720… (time component 01KVT0F720)

设置一个自定义时间戳,生成器便会内嵌那个确切时刻而非当前时间,同时仍用安全 RNG 填充随机段。2026-06-23T10:30:00.000Z 对应的 10 个字符时间分量是 01KVT0F720。这在为测试夹具播种确定性、按时间有序的标识符时很有用,也可用于迁移中回填记录,同时保持其可排序特性。

如何使用 ULID 生成器

  1. 1

    选择生成模式

    Standard 模式为每个 ULID 提供全新的 80-bit 随机数。Monotonic 模式保证同一毫秒内创建的 ULID 严格递增——在即便亚毫秒速率下也必须维持顺序的高吞吐插入场景中选它。

  2. 2

    设置数量、大小写,以及(可选的)自定义时间

    一次生成 1 到 50 个 ULID。输出默认为 UPPERCASE——即标准的 ULID 形式——也可切换为 lowercase。留空时间字段即盖上当前时间,或设定一个自定义时间戳,为测试夹具或回填记录内嵌特定时刻。

  3. 3

    生成并复制

    点击 Generate ULID。对任意单个值用 Copy,或用 Copy All 把整批以换行分隔的文本抓取下来,可直接粘贴进代码、种子文件或电子表格。

  4. 4

    解码 ULID 以读取其时间戳

    在 Decode 标签页粘贴任意 ULID,即可提取 48-bit 创建时间戳(UTC 与本地时间)、原始 Unix 毫秒值,以及 80-bit 随机数——全程在你的浏览器中完成,无需任何查询。

  5. 5

    在 ULID 与 UUID 之间转换

    在 ULID ↔ UUID 标签页粘贴一个 ULID 或一个 UUID;工具会自动识别输入并无损转换为另一种格式。把 ULID 存进 UUID 列,或把 ULID 交给只认 UUID 的系统,等需要可排序字符串时再转回来。

Common Errors

把同一毫秒内的 ULID 当作有序的

同一毫秒内创建的普通 ULID 共享时间前缀,但其随机尾段无序,因此相对顺序未定义。如果你在那种速率下依赖严格顺序,请改用单调递增模式。

✗ 错误
Standard mode, 3 IDs in one ms  →  order within the ms is random
✓ 正确
Monotonic mode, 3 IDs in one ms  →  …WMC < …WMD < …WME

期望转换后的 ULID 是合法的 UUIDv4

把 ULID 转换成 UUID 形式是对同样的 128-bit 重新编码;它不会设置 UUID 的版本与变体字段。结果是一个合法的 128-bit UUID 字符串,但若有库去检查那些位,它不会报告为版本 4 或 7。

✗ 错误
uuid.version(ulidToUuid(id))  →  not 4 (bits are the ULID's)
✓ 正确
Treat it as an opaque 128-bit value, or generate a real UUIDv7 instead

手工在 ULID 中使用小写 i、l、o

Crockford Base32 去掉了 I、L、O、U。解码器会把 I 和 L 映射为 1、把 O 映射为 0,但手工把这些字母敲进 ULID 容易出错。请复制 ULID,而不要重新键入。

✗ 错误
01ARYZ6S41TSV4RRFFQ69G5FAO  →  ambiguous O
✓ 正确
01ARYZ6S41TSV4RRFFQ69G5FAV  →  canonical characters only

ULID 的用途

保持有序的数据库主键
把 ULID 用作主键,便可获得 UUID 那种无需协调的生成方式,外加自增整数般的插入局部性。因为它们带时间前缀,新行会追加到 B-tree 索引末尾附近,而不像 UUIDv4 那样散落,从而在表增长时保持插入快速、索引紧凑。
无中央序列的分布式系统
在任意节点——服务、边缘 worker 或客户端——上生成标识符,无需共享计数器、无需碰撞协调,事后仍能把一切按创建时间排序。ULID 给微服务一个唯一、有序的键,而无需为分配它而往返数据库。
事件日志与消息 ID
用单调递增的 ULID 给事件、日志行或队列消息盖戳,即便许多消息在同一毫秒内产生,它们也能保持严格的时间顺序。对一个时间窗口做范围扫描,就变成了简单的字符串比较。
URL 安全的公开标识符
ULID 是 26 个不带连字符的字符、采用 URL 安全字母表,因此无需转义即可放进路径、文件名或请求头,且比 36 个字符的 UUID 更短。事后解码内嵌的时间戳,便能看到资源是何时创建的。
对接只认 UUID 的系统
在跟一个只接受 UUID 的数据库列或 API 打交道?生成可排序的 ULID,把它们转换成 UUID 形式用于存储或传输,等需要紧凑的可排序字符串时再转回来——128-bit 的值在两个方向上都被精确保留。
确定性的测试夹具
用自定义时间选项在选定时间戳上为测试播种 ULID,让夹具可复现且已按时间有序。在断言中解码它们,以验证你的代码记录的创建时间。

ULID 的工作原理

128-bit 布局:48-bit 时间 + 80-bit 随机数
一个 ULID 恰好是 128-bit。高 48-bit 是毫秒级 Unix 时间戳;低 80-bit 是随机数。以每字符 5 bit 的 Crockford Base32 编码,时间是 10 个字符、随机数是 16 个字符——共 26 个字符。首字符总是 7 或更小,因为 48-bit 填不满最高的那个 5-bit 分组。
Crockford Base32 编码
ULID 使用 Crockford Base32 字母表(0–9 和 A–Z,去掉 I、L、O、U)。去掉这四个字母避免了与数字 1 和 0 的混淆,并让解码器在处理字符串时大小写不敏感,在输入时把 I 和 L 映射为 1、把 O 映射为 0。该字母表是有序的,这正是编码后的字符串能与底层位以相同方式排序的原因。
按字典序可排序
因为时间戳是最高有效分量、且 Base32 字母表保序,把两个 ULID 当作字符串比较所得的结果,与比较它们的 128-bit 值相同,也与比较它们的创建时间相同。这正是普通的 ORDER BY 或数组排序无需额外索引即可产出时间顺序的原因。
毫秒内的单调性
ULID 规范的单调选项让同一毫秒内铸造的 ID 保持有序:某毫秒内第一个 ID 的随机数正常生成,该毫秒内随后的每个 ID 则是前一个随机值加一。本工具通过把 80-bit 随机数当作大端整数递增来实现这一点。
经由 crypto.getRandomValues 的安全随机性
那 80 个随机位由 crypto.getRandomValues(Web Crypto 的 CSPRNG)填充,而非 Math.random。在 80-bit 熵下,即便在同一毫秒内生成数百万个 ULID,碰撞概率也保持小到可忽略。
ULID ↔ UUID 是纯粹的重新编码
在 ULID 与 UUID 之间转换不改变任何位——它只是把同样的 128-bit 从 Crockford Base32 重新编码为带连字符的十六进制、或反向。因此往返是精确的:一个 ULID 转成 UUID 再转回来,与原值逐字节相同。请注意,ULID 的字节不会设置 UUID 的版本与变体字段,因此得到的 UUID 是一个合法的 128-bit 值,但并非带版本标记的 UUIDv4 或 v7。

ULID 最佳实践

高吞吐插入用单调递增模式
如果你的系统每毫秒能创建多个标识符且你依赖顺序,请生成单调递增的 ULID。普通 ULID 在一毫秒内是无序的;单调递增的则严格递增,因此无论你铸造得多快,整批都保持有序。
紧凑地存储 ULID
ULID 是 128-bit——当空间和索引大小要紧时,把它存成 16 个二进制字节或一个 UUID 类型的列,而非 26 个字符的文本字段。只在人类或 URL 看得到的边缘处才转成 Base32 字符串。本工具的 Convert 标签页能为你提供用于存储的 UUID 形式。
记住时间戳是可见的
ULID 会向任何能读到它的人暴露其创建时间。这对调试和排序很好,但如果暴露创建时间是个顾虑——比如在面向公众的标识符里——请权衡这一泄露,或在顺序无关紧要时改用完全随机的 UUIDv4。
始终用 CSPRNG 生成
唯一性保证取决于那 80 个随机位不可预测。请使用像 crypto.getRandomValues 这样的密码学安全来源(本工具正是如此)——绝不用 Math.random,它的可预测性可能让标识符碰撞或被猜中。
审慎地在 ULID 与 UUIDv7 之间抉择
两者都给出时间有序的 128-bit ID。想要最短的 URL 安全字符串就选 ULID;必须留在带版本与变体位的标准 UUID 格式中就选 UUIDv7。请在每个系统内统一用一种,需要跨越边界时再用 Convert 标签页。

ULID — 常见问题

什么是 ULID?
ULID(通用唯一、按字典序可排序的标识符,Universally Unique Lexicographically Sortable Identifier)是一个 128-bit 标识符,被设计为比 UUID 更可排序、更紧凑的替代方案。它写作 26 个字符的 Crockford Base32:前 10 个字符存放自 Unix 纪元起以毫秒计的 48-bit 时间戳,其余 16 个字符存放 80-bit 随机数。由于时间戳是最高有效部分、且 Base32 保持顺序,作为普通字符串比较时,晚创建的 ULID 总是排在更早的之后——因此一列 ULID 天然按时间有序。Crockford 字母表刻意去掉了字母 I、L、O、U,以避免与数字混淆,并让字符串大小写不敏感、URL 安全。引入 ULID 是为了解决随机 UUIDv4 的一个实际问题:随机标识符会散落在数据库索引各处,损害插入性能,而带时间前缀的 ULID 每次都落在索引末尾附近。
ULID 与 UUID——我该用哪个?
当你想要既唯一又能按创建时间自然排序的标识符时,用 ULID;当你明确需要一个不带内嵌时间戳的、不透明且完全随机的标识符时,用经典的 UUIDv4。关键差异:ULID 是 26 个字符的 Base32,而 UUID 是 36 个字符并带连字符,因此 ULID 更短,且无需转义即可用于 URL。ULID 编码了自己的创建时间,UUIDv4 则没有——这对排序和调试很有用,但如果你不希望暴露记录的创建时间,就值得注意。两者都是 128-bit,且都无需协调,因此二者的碰撞风险都可忽略不计。如果你的技术栈以 UUID 为标准但仍想要时间排序,UUIDv7(来自 UUID 生成器)在 UUID 格式中提供了类似的时间前缀设计——或者你也可以在这里生成 ULID,再用 Convert 标签页转换成 UUID。
ULID 可排序吗?
可以——这正是它的标志性特性。由于 48-bit 毫秒时间戳占据前 10 个字符,且 Crockford Base32 保持字典序,把 ULID 当作普通字符串排序就等于按创建时间排序。这在任何逐字节比较字符串的系统中都成立:数据库的 ORDER BY、有序集合、文件列表或简单的数组排序。其实际收益在于数据库性能:时间有序的键会追加到 B-tree 索引末尾,而不像 UUIDv4 那样随机散落,从而保持插入快速、索引紧凑。在单个毫秒内,普通 ULID 的顺序是随机的,因此如果你需要让同一毫秒内铸造的 ID 也严格有序,请使用单调递增模式——它会把随机数加一,确保每个值都大于上一个。
我如何解码一个 ULID 的时间戳?
把 ULID 粘贴进 Decode 标签页,工具会即时提取内嵌的创建时间,全程在你的浏览器中完成。它读取前 10 个字符,将其从 Crockford Base32 转回一个表示自 Unix 纪元起毫秒数的 48-bit 整数,并以 UTC 和你的本地时间、连同原始 Unix 毫秒值一同显示那个时刻。例如,标准 ULID 01ARYZ6S41TSV4RRFFQ69G5FAV 解码后是 1469918176385 毫秒,即 2016-07-30T22:36:16.385Z。其余 16 个字符是 80-bit 随机数,解码时不携带任何含义。这样读取时间戳在调试、审计记录何时创建,或快速核对某个标识符是否真的是 ULID 时都很方便——无需任何数据库查询。
什么是单调递增的 ULID?
单调递增的 ULID 即便对同一毫秒内生成的标识符也能保证严格有序。同一毫秒内创建的普通 ULID 共享同样的 10 个字符时间前缀,但它们的 80-bit 随机尾段相互独立,因此相对顺序未定义。单调递增生成法解决了这一问题:某毫秒内的第一个 ULID 取得全新随机数,该毫秒内随后的每个 ULID 都由前一个随机数加一产生。结果是一个每个值都严格大于前一个的序列,因此在紧凑循环中插入的一批仍保持完美有序。这对高吞吐系统——事件日志、消息队列、批量导入——很重要:在这些场景里,许多行的创建速度可能快过毫秒时钟的跳动,而你仍需要一个稳定且递增的键。
这个 ULID 生成器安全且私密吗?
两方面都是肯定的。每个 ULID 中的随机数都来自 crypto.getRandomValues,即浏览器密码学安全的随机数生成器——绝不用 Math.random——因此那 80 个随机位不可预测,两个 ULID 在同一毫秒内碰撞的概率微乎其微。同样重要的是,一切都在本地运行:ULID 的生成、解码和转换完全在你的设备上完成。任何内容都不会被上传、记录或存储,你可以打开开发者工具、在点击 Generate 时观察 Network 标签页保持静默来证实这一点。这一隐私属性正是在浏览器而非服务器上创建标识符的全部理由——服务器原则上可以保留它分发的每一个值的副本。
ULID 和 UUIDv7 有什么区别?
ULID 和 UUIDv7 都是把毫秒时间戳放在最前面的、时间有序的 128-bit 标识符,因此两者都按创建时间排序、都能高效索引——核心思路相同。区别在于格式与编码。ULID 呈现为 26 个字符的 Crockford Base32、不带连字符,更短且 URL 安全;UUIDv7 则以标准的 36 个字符、带连字符的十六进制 UUID 布局呈现,并在固定位置携带版本与变体位,因此它是任何 UUID 库都接受的、完全合法的 RFC 9562 UUID。当你必须留在 UUID 生态中(UUID 数据库列、UUID 类型的 API)时选 UUIDv7;当你想要最短的可排序字符串时选 ULID。由于两者都是 128-bit,你可以在这里生成一个 ULID,并用 Convert 标签页把它转换成 UUID 形式,或用 UUID 生成器 生成一个 UUIDv7。

Bcrypt 哈希生成器与验证器

安全工具

在线生成并验证 bcrypt 密码哈希——可调成本因子,支持 $2b$/$2a$/$2y$ 前缀。100% 在浏览器中运行,密码绝不上传。

JWT 解码器 · 在线解码工具

安全工具

免费 JWT 解码器,在线即时解码 JWT 令牌。查看头部、载荷、签名以及过期时间、算法和声明详情。100% 浏览器本地运行——令牌绝不离开你的设备。无需注册、无跟踪。

JWT 编码器与生成器

安全工具

免费在线 JWT 生成器与编码器。构建头部和载荷,使用 HS256、RS256 或 ES256 即时签名。100% 浏览器本地运行——你的密钥和私钥绝不离开设备。

免费 JWT 密钥生成器 — HS256/384/512

安全工具

为 HS256/384/512 生成强壮、符合 RFC 规范的 JWT 密钥——100% 在浏览器中运行,绝不发往服务器。支持 base64url、base64 或 hex,可复制到 .env。

在线 MD5 哈希生成器与文件校验工具

安全工具

在线生成 MD5、SHA-256、SHA-1、SHA-512 哈希值 — 完全免费,浏览器本地运算,无需注册。支持文本和文件哈希、校验和验证、哈希值对比,一键复制,数据绝不离开你的设备。

随机密码生成器 — 自定义长度、强度与安全性

安全工具

免费在线随机密码生成器,一键生成高强度安全密码。支持自定义长度、字符类型,批量生成多个密码。所有密码仅在浏览器本地生成,不上传不存储。