UUID v2生成器

Generate DCE Security UUID v2 with local domain and ID

点击"生成"以创建 UUID
注意:UUID v2 将本地域和 ID 编码到 UUID 结构中
Note:UUID v2 是一种遗留格式,为 DCE 安全上下文定义。在现代应用中很少需要。对于通用唯一 ID,推荐使用 UUID v4

什么是 UUID v2?

UUID v2 是 DCE 安全 UUID 版本,作为分布式计算环境(DCE)规范的一部分标准化,并在 RFC 4122 中引用。它通过将 POSIX 用户或组标识符(UID/GID)嵌入时间戳字段来扩展 UUID v1。

结构类似于 UUID v1,但 32 位 time_low 字段被替换为 32 位本地标识符(例如 POSIX UID),1 字节的 local_domain 字段标识它是哪种本地 ID。因此时间戳被截断,降低了其精度和唯一性保证。

UUID v2 在现代软件中极为罕见。大多数开发人员永远不需要生成一个。本页记录了该格式,以便完整性和帮助解码遗留系统中遇到的 UUID v2 值。

UUID v2 结构

UUID v2 与其他 UUID 版本具有相同的 128 位连字符格式。字段与 UUID v1 的区别如下:

字段位数用途
local_id32<code>local_id</code>——32 位本地域标识符(例如来自 <code>/etc/passwd</code> 的 POSIX UID),替换 UUID v1 的 time_low 字段
time_mid16<code>time_mid</code>——截断的 UUID v1 时间戳的中间 16 位
time_hi+version16<code>time_hi_and_version</code>——最高 12 位时间戳,版本半字节设为 <code>2</code>
variant+clock_hi8<code>clock_seq_hi_and_reserved</code>——变体位加上时钟序列的高位部分
local_domain8<code>local_domain</code>——域标识符:<code>0</code> = POSIX 用户(UID),<code>1</code> = POSIX 组(GID),<code>2</code> = 组织
node48<code>node</code>——生成主机的 48 位 MAC 地址

示例:000003e8-92e0-21ef-8000-325096b39f47——local_id 0x000003e8 = UID 1000,local_domain 0x00 = POSIX 用户

Note:由于 local_id 字段替换了 time_low 字段,UUID v2 中的时间戳只有 28 位宽(而 UUID v1 中有 60 位)。这将时间戳精度降低到大约 7.2 分钟——在同一 7 分钟窗口内从同一主机/域/local_id 组合生成的 UUID 可能不是唯一的。

本地域值

local_domain 字节指定 UUID 中嵌入的本地标识符类型:

0POSIX_UID
POSIX 用户 ID——来自 <code>/etc/passwd</code> 的数字 UID,可通过 <code>os.getuid()</code> 获取
1POSIX_GID
POSIX 组 ID——来自 <code>/etc/group</code> 的数字 GID,可通过 <code>os.getgid()</code> 获取
2ORG
组织——自定义 32 位组织标识符;语义由应用程序定义

域值由 DCE 规范定义。值 3–255 保留。实际上,只有域 0(人员/UID)在实际 UUID v2 值中常见。

为什么 UUID v2 很少使用

三个特性使 UUID v2 对于大多数现代应用程序来说不切实际:

粗糙的时间戳分辨率

时间戳被截断为 28 位(大约 7.2 分钟粒度)。在该窗口内,同一主机上具有相同 local_id 和域的 UUID 不是唯一的——规范依赖 clock_seq 字段来区分它们,将唯一性限制为每 7 分钟窗口 64 个值。

没有标准库支持

与 UUID v1 和 v4 不同,大多数 UUID 库不支持 UUID v2。uuid npm 包、Python 的 uuid 模块和 Java 的 java.util.UUID 都省略了 v2。需要自定义实现。

POSIX 特有的语义

本地域概念(UID/GID)本质上是 POSIX 特有的,在 Windows、嵌入式系统或 POSIX 用户 ID 概念不存在的云环境中没有实际意义。

Warning:不要在新项目中使用 UUID v2。该格式对于通用唯一 ID 相比 UUID v4 或 v7 没有任何优势。如果你在遗留系统中遇到了 UUID v2,请使用此工具解码其字段。对于新开发,请使用 UUID v4

历史背景

UUID v2 是在 1990 年代初期作为开放软件基金会的分布式计算环境(DCE/RPC)的一部分定义的。目标是创建可以携带授权上下文的 UUID——具体来说,是让 RPC 服务器在没有单独身份验证步骤的情况下识别调用用户。

DCE 安全模型假设了一个同质 POSIX 环境,其中每个节点都参与共享的 UID/GID 命名空间。嵌入的 UID 将让服务器快速检查访问控制列表,而无需往返目录服务。

  • 互联网从同质 POSIX 环境转向异质云架构
  • 现代身份验证使用令牌(JWT、OAuth)而非标识符中嵌入的 UID
  • UUID v4(完全随机)和 UUID v7(按时间排序)涵盖了唯一标识符的实际用例
  • DCE/RPC 本身已不再广泛使用

RFC 4122(2005 年)通过引用 DCE 规范包含了 UUID v2,但故意省略了详细的生成算法——注意它是由 DCE 而非 IETF 定义的。

RFC 9562(2024 年),更新了 UUID 标准,为了历史完整性保留了 UUID v2,但继续指出其 POSIX 特有性质和 IETF 标准中缺少完整生成算法的问题。

UUID v2 vs UUID v1

UUID v2 源自 UUID v1。以下是它们的对比:

方面UUID v1UUID v2
时间戳位数60 位(约 100 纳秒精度)28 位(约 7.2 分钟精度)
本地标识符32 位 POSIX UID/GID
本地域不存在0=UID,1=GID,2=组织
节点字段MAC 地址MAC 地址
库支持广泛支持很少支持
标准RFC 4122 / RFC 9562DCE 规范(RFC 4122 引用)
实际用途遗留时间戳排序 ID(Cassandra)仅 DCE 安全上下文

UUID v2 对通用用途比 UUID v1 没有任何优势,在大多数方面严格更差。没有理由在新开发中选择 UUID v2。

代码示例

UUID v2 在标准库中没有原生支持。以下示例展示如何处理 UUID v2 值:

Python——手动实现

Python
import uuid, struct, time

def uuid_v2(local_id: int, local_domain: int = 0) -> str:
    """
    Generate a DCE Security UUID (v2).
    local_domain: 0 = POSIX UID, 1 = POSIX GID, 2 = Org
    local_id: 32-bit unsigned integer (e.g. os.getuid())
    """
    # Get a v1 UUID for the time and node fields
    v1 = uuid.uuid1()
    fields = list(v1.fields)  # [time_low, time_mid, time_hi_version, clock_seq_hi_variant, clock_seq_low, node]

    # Replace time_low with local_id
    fields[0] = local_id & 0xFFFFFFFF

    # Replace version nibble: clear lower 12 bits of time_hi, set version 2
    fields[2] = (fields[2] & 0x0FFF) | 0x2000

    # Replace clock_seq_low with local_domain
    fields[4] = local_domain & 0xFF

    return str(uuid.UUID(fields=tuple(fields)))


import os
print(uuid_v2(os.getuid(), local_domain=0))   # POSIX UID
print(uuid_v2(os.getgid(), local_domain=1))   # POSIX GID

Go——注意

Go
// The standard "github.com/google/uuid" package does NOT support v2.
// You would need to implement it manually, similar to the Python example above.
// Most Go developers use v4 or v7 for new projects.
import "github.com/google/uuid"

v4 := uuid.New()          // v4 — recommended for most use cases
v7, _ := uuid.NewV7()     // v7 — time-ordered, ideal for database primary keys

JavaScript——提取字段

要从现有 UUID v2 字符串中提取 local_id 和域:

JavaScript
// Extracting fields from a UUID v2 string
const uuidStr = '000003e8-1234-2abc-8200-a1b2c3d4e5f6'
//               ^^^^^^^^ ^^^^ ^    ^^
//               local_id      ver  variant+clockSeqHi
//                                  ^^ = local_domain (00 = POSIX UID)

const parts = uuidStr.split('-')

const localId     = parseInt(parts[0], 16)       // → 1000 (0x3e8)
const version     = parseInt(parts[2][0], 16)    // → 2
const localDomain = parseInt(parts[3].slice(2), 16) // low byte of octet pair

const DOMAIN_NAMES = ['POSIX UID', 'POSIX GID', 'Org']
console.log(`Local ID: ${localId}`)                       // Local ID: 1000
console.log(`Version:  ${version}`)                       // Version:  2
console.log(`Domain:   ${DOMAIN_NAMES[localDomain]}`)     // Domain:   POSIX UID
Note:google/uuid Go 包通过 uuid.NewDCEGroup()uuid.NewDCEPerson() 支持 UUID v2 生成——是少数支持的主流库之一。

常见问题

我可以在 JavaScript 中生成 UUID v2 吗?
没有标准库支持 JavaScript 中的 UUID v2 生成。你需要手动构建字节:取一个 UUID v1,用你的本地标识符替换 time_low 字段(字节 0–3),将字节 9 设置为你的域值,并将版本半字节设置为 2。此工具不生成 UUID v2——它只解码它们。
local_id 字段包含什么?
local_id 是一个 32 位无符号整数,其含义取决于 local_domain 字节。对于域 0,它是运行进程的用户的 POSIX UID(例如 Linux 系统上第一个非 root 用户为 1000)。对于域 1,它是 POSIX GID。对于域 2,含义由应用程序定义。
UUID v2 中的时间戳可靠吗?
只能作为粗略指示。因为 60 位 UUID v1 时间戳中只保留了 28 位,有效精度约为 7.2 分钟。你可以解码大致的生成时间,但不能精确。在 7 分钟窗口内,来自同一主机具有相同 local_id 和域的多个 UUID v2 值将具有相同的时间戳。
哪些系统仍然使用 UUID v2?
UUID v2 主要出现在 1990 年代的遗留 DCE/RPC 系统、某些版本的 Microsoft DCOM(基于 DCE/RPC)以及较旧的分布式计算中间件中。现代系统几乎都使用 UUID v4 或 v7。
为什么 RFC 4122 不包含 UUID v2 算法?
RFC 4122 明确指出 UUID v2 生成算法由 DCE 规范定义,而非 IETF。由于 IETF 对 DCE 规范没有权限,他们只包含了引用。这就是为什么大多数遵循 RFC 4122 的 UUID 库省略了 UUID v2 支持。
UUID v2 与 GUID 相同吗?
不。GUID(全局唯一标识符)是 Microsoft 对 UUID 标准的实现。Microsoft COM 内部使用 UUID v1 和 v4 GUID。尽管 UUID v2 和 Windows GUID 基础结构都源自同一 DCE/RPC 起源,但 UUID v2 不被 Windows GUID 基础结构使用。