通用唯一识别码

历史

UUID最初用于Apollo 网络计算系统（NCS），后来用于开放软件基金会（OSF）分布式计算环境（DCE）。DCE UUID的初始设计基于NCS UUID，其设计受Domain/OS 中定义和使用的（64位）唯一标识符的启发，这是一个也由Apollo Computer 设计的操作系统。后来，Microsoft Windows 平台采用DCE 设计作为全局唯一标识符（GUID）。 RFC 4122 为 UUID 注册了一个URN 名字空间，并制定了早期的规范。当 RFC 4122 作为 IETF 标准发布时，ITU 基于先前的标准和RFC 4122 早期版本标准化了UUID。

标准

UUID 由开放软件基金会（OSF）标准化，作为分布式计算环境（DCE）的一部分。
UUID 被作为ISO/IEC 11578:1996 "Information technology – Open Systems Interconnection – Remote Procedure Call (RPC)" 中的一部分，最近在ITU-T Rec. X.667 | ISO / IEC 9834-8：2005 规范中。
互联网工程任务组（ Internet Engineering Task Force，IETF）公布的标准RFC 4122，技术上等同于ITU-T Rec. X.667 | ISO/IEC 9834-8。

编码

UUID 的二进制编码因系统而异。许多系统完全以大端序 (big-endian) 编码 UUID 。
例如，00112233-4455-6677-8899-aabbccddeeff 编码为字节00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff。
其他系统，特别是Microsoft 在其COM/OLE 库中对UUID 进行编组，使用混合端格式，其中 UUID 的前三组是小端序/小尾序 (little-endian) ，后两组是大端序/大尾序 (big-endian)。
例如，00112233-4455-6677-8899-aabbccddeeff 编码为字节33 22 11 00 55 44 77 66 88 99 aa bb cc dd ee ff。

版本

对于 "变体(variants)1" 和 "变体2"，标准中定义了五个"版本(versions)"，并且在特定用例中每个版本可能比其他版本更合适。
版本由M 字符串中指示。
"版本1" UUID 是根据时间和节点ID（通常是MAC地址）生成; 
"版本2" UUID是根据标识符（通常是组或用户ID）、时间和节点ID生成; 
"版本3" 和 "版本5" 确定性UUID 通过散列(hashing) 名字空间(namespace) 标识符和名称生成; 
"版本4" UUID 使用随机性或伪随机性生成。

Nil UUID

"nil" UUID是一个特例，值为00000000-0000-0000-0000-000000000000 ; 也就是说，所有位都设置为0。

版本1（日期时间和MAC地址）

"版本1" 连接“节点” 的 48-bit MAC地址（即生成UUID的计算机），具有60位时间戳，自1582年10月15日午夜起协调世界时（UTC）以来的100纳秒间隔数，公历首次采用的日期。RFC 4122声明时间值在公元3400左右滚动，取决于所使用的算法，这意味着60-bit 时间戳是有符号数量。但是，某些软件（如libuuid库）将时间戳视为无符号，将转存时间设置为5236 AD。
13-bit 或 14-bit“无统一(uniquifying)”时钟序列扩展了时间戳，以便处理处理器时钟不能足够快地前进的情况，或者每个节点有多个处理器和UUID 生成器的情况。对于每个"版本1" UUID 对应于空间（节点）和时间（间隔和时钟序列）中的单个点，两个正确生成的"版本1" UUID 无意中相同的可能性实际上为零。由于时间和时钟序列总共74位，每个节点id 可以生成（ 或 18 sextillion(大数名词，千的七次方，十万亿亿)）"版本1" UUID，每个节点id 的最大平均速率为每秒1630 亿。
与其他UUID 版本相比，基于来自网卡的MAC 地址的"版本1" 和 "版本2" UUID，部分依赖于由中央注册机构发布的标识符，即 MAC 地址的组织唯一标识符（OUI）部分，由 IEEE 发布给网络设备制造商。基于网卡MAC地址的"版本1" 和 "版本2" UUID 的唯一性还取决于网卡制造商正确地为其卡分配唯一的MAC地址，这与其他制造过程一样容易出错。
使用节点的网络MAC 地址作为节点ID ，意味着可以将"版本1" UUID 追溯回创建它的计算机。文档有时可以跟踪到通过文字处理软件嵌入到它们中的UUID 创建或编辑它们的计算机。在找到Melissa 病毒的创建者时使用了这个隐私漏洞。
RFC 4122 确实允许"版本1"（或2）UUID 中的MAC 地址被随机的48 位节点id 替换，因为该节点没有MAC 地址，或者因为不希望暴露它。在这种情况下，RFC要求节点id 的第一个八位字节的最低有效位应设置为1，这对应于MAC地址中的多播位，并且设置它用于区分随机生成节点id 的 UUID 和基于来自网卡的MAC 地址的UUID，网卡通常具有单播MAC 地址

版本2（日期时间和MAC地址，DCE安全版本）

RFC 4122 保留了“DCE security” UUID 的 "版本2" ; 但它没有提供任何细节。因此，许多 UUID 实现省略了"版本2" 。但是， "版本2" UUID 的规范由DCE 1.1 身份验证和安全服务规范提供。
"版本2"   UUID 类似于"版本1" ，除了时钟序列的最低有效8 bits 被“本地域(local domain)”号替换，并且时间戳的最低有效32 bits 由在指定本地域内有意义的整数标识符替换。在 POSIX 系统上，本地域号0 和 1 分别用于用户ID（UIDs）和组ID（GIDs），其他本地域号用于站点定义。在非POSIX 系统上，所有本地域号都是站点定义的。
在 UUID 中包含40 bits 域/标识符(domain/identifier) 的能力需要权衡。一方面，40 bits 允许每个节点id 有大约1万亿个 域/标识符 值。另一方面，时钟值被截断为28 个最高有效位，而 "版本1" 中为60 bits；"版本"2 UUID 中的时钟每429.49秒 “标记(tick)” 一次，略多于7分钟，而不是"版本1" 中的每100 纳秒；并且，"版本2" 仅 6 bits 时钟序列，"版本1" 中 14 bits；每7分钟时钟周期内，每个 节点/域/标识符(node/domain/identifier) 只能生成64个唯一的UUID，而版本1的时钟序列值为16,384个。 因此，"版本2" 可能不适合于以每个 节点/域/标识符 生成UUID 的情况，其速率约7秒以上1次。

版本3和版本5（基于名字空间名称）

"版本3" 和 "版本5" 的 UUID 被生成散列(hashing)一个名字空间标识符和一个名称。"版本3" 使用 MD5 作为散列算法， "版本5" 使用 SHA1。
名称空间标识符本身就是一个UUID。该规范提供了UUID 用来表示名字空间为了统一资源定位符(URLs)，完整域名、对象标识符和X.500 轻型目录访问协议 ; 但任何所需的UUID都可以用作名字空间指示符。
要确定与给定名字空间和名称对应的"版本3" UUID，名字空间的UUID 将转换为字节串，与输入名称连接，然后用MD5 进行散列，产生 128 bits。然后将六或七位替换为固定值，即 4-bit 版本（例如“版本3”的 0011），以及 2-bit 或 3-bit UUID “变体(variant)”（例如 10 指示RFC 4122 UUID，或 110 指示传统Microsoft GUID） 。由于预定了6或7 bits，因此只有121 或 122 bits 有助于UUID 的唯一性。
"版本5" UUID 类似，但使用SHA1 而不是MD5。由于 SHA1 生成 160-bit 摘要，因此在替换版本和变体位之前，摘要将截断为128-bits。
"版本3" 和 "版本5" UUID 具有相同名称空间和名称，将映射到同一UUID ；除了暴力搜索之外，名字空间和名称都不能从UUID 中确定。
RFC 4122 推荐 "版本5"（SHA1）而不是"版本3"（MD5），并建议不要使用任一版本的UUID 作为安全凭证。

版本4（随机）

随机生成"版本4" UUID。与其他UUID 一样，4-bit 用于指示"版本4"，2-bit 或 3-bit 用于指示变体(variant)（10 或 110 分别用于 变体1 和 2）。因此，对于变体1（即大多数UUID），随机 "版本4" UUID 将具有6 个预定的变体和版本位，为随机生成的部分留下122位，"版本4" 变体1 UUID 可能共计 或（5.3 undecillion，大数名词）个。 "版本4" 变体2 UUID （传统GUID）的可能有一半，因为可用的随机位少一个，变量消耗3 bits。
一些伪随机数发生器缺少必要的熵来产生足够的伪随机数。例如，使用伪随机数生成器的WinAPI GUID 生成器已被证明可生成遵循可预测模式的UUID。 RFC 4122 建议“在各种主机上生成UUID 的分布式应用程序必须愿意依赖所有主机上的随机数源。如果这不可行，则应使用名称空间变体。”

碰撞

当多次生成相同的UUID 并将其分配给不同的指示对象时，就会发生冲突。对于使用来自网卡的唯一MAC地址的标准 版本1和2 的 UUID ，只有当实施与标准不同时，无论是无意还是故意，都可能发生冲突。
与 版本1 和 版本2 相比， UUID 使用随机生成的节点ID，基于散列的 版本3 和 版本5 的 UUID ，以及随机 版本4 的 UUID ，即使没有实现问题也可能发生冲突，尽管可能性很小，通常可能是忽略。可以基于对生日问题的分析来精确地计算该概率。
例如，至少碰撞一次具有50％的概率，根据 版本4 需要生成的UUID 的数量是，计算如下：
这个数字相当于大约85 年每秒产生10 亿个UUID ，每个UUID 16 bytes/字节，包含这么多UUID 的文件，大约 45 艾字节(EB)，比当前存在的最大数据库大很多倍，它们都在数百PB的数量级。
最小数必须查找碰撞要的概率来生成 版本4 的 UUID 的 p 由下式近似计算：
因此，在 103 万亿 个 版本4  UUID 中找到重复的概率是(十亿分之一)。

使用

重要用途包括ext2/ext3/ext4 文件系统用户空间工具（e2fsprogs 使用 util-linux 提供的libuuid），LUKS 加密分区，GNOME，KDE 和 Mac OS X，其中大部分源自曹子德(Theodore Ts'o) 的实现。
Solaris 中 UUID 的一种用途（使用Open Software Foundation实现）是识别正在运行的操作系统实例，以便在内核崩溃的情况下将故障转储数据与故障管理事件配对。

COM

Microsoft的组件对象模型（COM）中使用了几种GUID ：
IID - 接口标识符; （在系统上注册的那些存储在Windows注册表中）[HKEY_CLASSES_ROOT\Interface]
CLSID - 类标识符; （存储在）[HKEY_CLASSES_ROOT\CLSID]
LIBID - 类型库标识符; （存储于）[HKEY_CLASSES_ROOT\TypeLib]
CATID - 类别标识符; （它在一个类中的存在将其识别为属于某些类别类别）[HKEY_CLASSES_ROOT\Component Categories]

作为数据库密钥

UUID 通常用作唯一键的数据库表。
Microsoft SQL Server 版本4 中的NEWID 函数 Transact-SQL 返回标准随机 版本4 UUID，而 NEWSEQUENTIALID 函数返回类似于UUID 的128 位标识符，这些 UUID 将按顺序提升，直到下次系统重新引导。
尽管名称如此，但 Oracle Database SYS_GUID 函数不会返回标准GUID；相反，它根据主机标识符和进程或线程标识符返回一个16字节的128 位 RAW 值，有点类似于GUID。
PostgreSQL 包含一个UUID 数据类型，并且可以通过使用模块中的函数生成大多数版本的UUID。
MySQL 提供了一个UUID 函数，它生成标准 版本1 UUID。
当 UUID 用作主键时，版本3、4和5 UUID 的随机性以及 版本1和2 UUID 内的字段的排序可能会产生数据库位置或性能问题。例如，2002年 Jimmy Nilsson 报告说，当用作密钥的版本4 UUID 被修改为包含基于系统时间的非随机后缀时，Microsoft SQL Server 的性能显着提高。Nilsson 承认，这种所谓的“COMB”（组合时间-GUID）方法使UUID非标准并且更有可能被复制，但 Nilsson 仅在应用程序中要求唯一性。