这是一篇笔者自我搬运过去的博文,如有雷同,绝非巧合。
UUID概述和基本规则
UUID(Universally Unique Identifier)是通用唯一标识码,在信息系统中常用于识别信息项目。
UUID是一种标准技术,可以根据规定的标准方法生成,而不依赖某种中央系统或特定软件的注册和分配。UUID的设计目标是提供编码和标识的广义唯一性,按照标准实现生成的UUID重复UUID码概率接近零,基本可以忽略不计。
UUID在实际应用中的主要问题是占用空间较大(36个字节),在数据库或者网络传输过程中有一定的存储和传输的代价。所以有人提出了改进和替代方案如NanoID、pushID等等,有时间再另外讨论。
标准的UUID的由一组32位的16进制数字组成(hex编码),分为8+4+4+4+12五组,使用"-"符号进行分割,理论上的可用总数为2的128次方。其编码规则如下(图):
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
其中M是类型号(12345,随后说明),N是固定值(8,9,A,B)。
UUID编码版本
现有的UUID编码方式有五个版本(类型),它们的定义和参考实现如下:
- V1 基于时间
基于当前时间戳、随机数和机器MAC地址(或者IP地址)
-
V2 DCE(Distributed Computing Environment) 和基于时间的类型,但会把时间戳的前4位换成POSIX系统的ID
-
V3 基于名字 通过计算名字和名字空间的MD5散列值得到。
-
V4 基于随机数或者伪随机数生成 这个版本使用的最为广泛,我们随后详细讨论。
-
V5 基于命名空间和SHA1 基于名字的UUID算法类似,只是改进使用SHA1作为其摘要算法
可以看到,这5个版本并不是时间或者改进的版本,其实是5种类型,开发者可以根据实际需求选择使用。
UUIDv4 Javascript实现
作为最常用的一类UUID,我们这里主要讨论V4的实现,这个实现可以使用随机算法生成,而不依赖任何外部系统、命名规则和参考信息,实现和操作最为简单。有多简单?下面是其实现的JS代码:
const uuidv4 = ()=>
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
.replace(/[xy]/g, c=>(c=="x"? 0xF & Math.random() * 16 : 0x3 & Math.random() * 16 | 8 )
.toString(16));
console.log(uuidv4());
这个实现的要点如下:
- 使用标准UUID模板字符串
- 模板字符串中有版本4固定标记
- 动态标记分为x和y两类
- 替换使用正则匹配结合匹配回调函数进行处理
- 将x替换为0-15中随机整数对应的Hex值
- 将y替换为8-11中随机整数对应的Hex值
所以,最后一个问题就是,为什么N的取值是8~B呢?