UUID简要研究和JS实现

199 阅读3分钟

这是一篇笔者自我搬运过去的博文,如有雷同,绝非巧合。

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

0.png

其中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呢?