简体中文

开发者工具·UUID生成器

crypto.getRandomValues 如何将 16 个随机字节转换为 v4 UUID

· 工作原理

uuid 密码学 浏览器 API

十六个随机字节,突出显示版本和变体位字段
原始 ToolAcre 矢量图

版本 4 UUID 是来自加密安全生成器的 16 bytes,并覆盖了六位。这篇文章将字节从 Web Crypto 调用逐步介绍到熟悉的 36 个字符的字符串。

服务器应答之前需要的 ID——为什么客户端生成以离线优先的形式、乐观的 UI 和批量导入的形式出现

离线表单在服务器响应之前可能需要标识符,而乐观的 UI 可能会同时创建多个对象。 UUIDv4 设计为独立生成,无需中央计数器。它不是用户身份的证明,也不是可以安全地代替身份验证的秘密。如果您的数据库需要按创建时间排序的值,则随机 v4 ID 不会排序;这是一个单独的模式决策,而不是削弱其随机性的原因。

crypto.getRandomValues 实际上做了什么——从操作系统的熵源填充类型化数组,而不是从 JavaScript 公式

crypto.getRandomValues 使用来自浏览器平台的加密安全随机生成器的 16 bytes 填充 Uint8Array。它不会从 Date.now() 或 Math.random() 派生值。操作系统和浏览器实现底层熵源,因此 JavaScript 代码接收字节而不是实现随机数公式本身。如果不存在安全源,ToolAcre 将拒绝生成标识符。

覆盖字节 6 和字节 8 — 版本半字节如何变为 4,变体位如何变为 10xx,以及为什么仅丢失 6 位

RFC 9562 描述了版本半字节和变体字段。从十六个随机字节开始,将字节 6 的高四位设置为二进制 0100(版本 4),并将字节 8 的高两位设置为 10(标准变体)。实现使用 (byte6 & 0x0f) | 0x40 和(byte8 和 0x3f)| 0x80。 6 位被覆盖,在 UUIDv4 方案下留下 122 个随机位。这些常量位不会使剩余字节的随机性降低。

从字节到 8-4-4-4-12 — 十六进制编码、小写输出和连字符放置(按照标准定义)

需要时将每个字节编码为两个带有前导零的十六进制字符。在 4、6、8 和 10 bytes 之后插入破折号,生成熟悉的 8-4-4-4-12 十六进制字符组。有效的 v4 字符串在其第三组的开头有一个 4,在其第四组的开头有 8、9、a 或 b 之一。格式化不会增加熵;它仅使底层 128 位值可与需要 UUID 文本形式的工具进行互操作。

工作示例 - 通过屏蔽和格式化跟踪一个 16 字节缓冲区到其最终的 UUID 字符串

跟踪说明性字节 00 11 22 33 44 55 F6 77 38 99 AA BB CC DD EE FF。在字节 6 处屏蔽 F6 产生 46;字节 8 处的掩码 38 产生 B8。经过小写十六进制格式化和破折号后,结果为 00112233-4455-4677-b899-aabbccddeeff。这是一个故意固定的教学示例,而不是在生产中重复使用的标识符。为每个真实对象生成一个新的对象,并自行比较版本和变体位置。

crypto.randomUUID() 作为一调用快捷方式 - 新方法可以为您做什么以及它不可用的地方

在安全源上,crypto.randomUUID() 在一次调用中执行 v4 生成和格式化。 ToolAcre 在可用的情况下使用它,否则使用上面的显式位操作回退到 getRandomValues。浏览器可用性因上下文而异:randomUUID 仅限于安全上下文,而 getRandomValues 可能仍存在于 HTTP LAN 页面上。两个分支都不会退回到 Math.random 只是为了保持按钮明显工作。

这不包括基于时间(v1,v7)和基于名称(v3,v5)的版本,它们需要与随机字节不同的输入

此机制不描述基于时间的 v1 或 v7 标识符、基于名称的 v3/v5 标识符或实验性 v8 布局。随机 UUID 的碰撞概率非常低,并且具有良好的随机性,但并不是数学上绝对不可能发生碰撞。在不独立考虑保密性、生命周期和授权的情况下,v4 UUID 本身不应用作访问控制检查或密码重置令牌。

要点:安全随机性是整个工作 — ToolAcre UUID 生成器从同一个浏览器 CSPRNG 中提取,因此您复制的内容就是您的代码将生成的内容

安全随机性就是工作。 ToolAcre UUID 生成器使用浏览器的 CSPRNG,强制执行版本和变体位,并为复制的值提供格式良好的检查。将生成的结果与字节布局示例进行比较,然后仅将新的、唯一的输出用于应用程序实际分配的角色。