uuid是什么

UUID的全称是Universally Unique Identifier,中文为通用唯一识别码。uuid的出现是为了让分布式系统可以不借助中心节点,就可以生成uuid来标识一些唯一的信息。

本身是由一组32位数的16进制数字所构成,故UUID理论上的总数为1632=2128,约等于3.4 x 1038。也就是说若每纳秒产生1兆个UUID,要花100亿年才会将所有UUID使用完,也就是说最多100亿年的时间,UUID将必定出现重复,不过100亿年地球是否存在也似乎不确定,暂时不必考虑那么长远。

表现形式

UUID也是需要像身份证号一样事先制定一些简单的规则进去的,它的标准型式包含32个16进制数字,以连字号分为五段,表现形式为8-4-4-4-12的32个字符,如下所示:

  1. xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

其中M与N都有特殊含义,M表示UUID版本,目前只有五个版本,即只会出现1,2,3,4,5,数字 N的一至三个最高有效位表示 UUID 变体,目前只会出现8,9,a,b四种情况。(N只会是8,9,a,b)

各个版本简介

版本一:基于时间的UUID

通过当前时间戳,机器MAC地址生成。
由于在算法中使用了MAC地址,这个版本的UUID可以保证在全球范围的唯一性。(小概率重复)

但与此同时,因为它暴露了电脑的MAC地址生成这个UUID的时间,这就是这个版本UUID被诟病的地方。

Nodejs使用示例

  1. const uuidv1 = require('uuid').v1;
  2. const logger = console.log;
  3. logger('uuid v1版本:%s', uuidv1());
  4. // uuid v1版本:10e10f40-bd02-11e9-b241-97aa7a999bec

其中,最后的12个字符97aa7a999bec就是我电脑网卡的MAC地址

版本二:DCE安全的UUID

DCE安全的UUID和基于时间的UUID算法相同,但会把时间戳的前4位置换为POSIX的UID或GID。
不过,在UUID的规范里面没有明确地指定,所以基本上所有的UUID实现都不会实现这个版本。

版本三:基于名字空间的UUID(MD5)

由用户指定1个namespace和1个具体的字符串,通过MD5散列,来生成1个UUID;
根据规范描述,这个版本的存在是为了向后兼容?平时这个版本我们也很少用到

Nodejs使用示例

  1. // nodejs uuid源码中预定义的命名空间
  2. generateUUID.DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
  3. generateUUID.URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
  4. //使用示例
  5. const uuidv3 = require('uuid/v3');
  6. const logger = console.log;
  7. logger('uuid v3版本:%s', uuidv3('myString', uuidv3.DNS))
  8. // 21fc48e5-63f0-3849-8b9d-838a012a5936

版本四:基于随机数的UUID

这个版本的UUID是使用最多的,它的本质是根据随机数或者伪随机数来生成UUID,最大的问题就是这种重复率的问题,这一类型的UUID的重复率是可以计算出来的,所以大型长期的网站还是不建议采用这个版本的,当用久了后重复的概率越来越大,遇到的问题将越来越多。

JavaScript 实现

  1. function uuidv4() {
  2. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  3. var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
  4. return v.toString(16);
  5. });
  6. }

Nodejs使用示例

  1. const uuidv4 = require('uuid/v4');
  2. const logger = console.log;
  3. logger('uuid v4版本:%s', uuidv4())

版本五:基于SHA1散列算法的UUID

这个版本与第三版本的UUID类似,但使用的散列算法不同 ,它利用SHA1 代替了 MD5,其余和第三个版本一样,但是相比于第三步版 更加推荐使用这一版本。

SHA1和MD5的区别
首先它们两个都是散列函数,对于SHA1来说,长度小于2^64位的消息,则会产生一个160位的消息摘要,而MD5最显著和最重要的区别是它的摘要比SHA1摘要少32 位,它只产生出一个128位的消息摘要,如果使用强行破解技术,SHA-1相比于MD5有更大的强度。
在Nodejs的uuid的实现中,V5与V3实现唯一不一致的就是散列函数不同。

  1. // v3版本
  2. crypto.createHash('md5').update(bytes).digest();
  3. // v5版本
  4. crypto.createHash('sha1').update(bytes).digest();

总结

从几个版本的定义来看,感觉都不是特别完美,可能版本4是平时用得最多的,但是在现实的业务场景中,考虑到可读性、唯一性、长度,我们一般也不会选择UUID当做数据库的主键。


相关文章
唯一识别码之UUID入门与实战
https://juejin.cn/post/6844903917256441864

关于UUID的二三事
https://mp.weixin.qq.com/s?src=11&timestamp=1632790592&ver=3341&signature=6ifhON7E614o2885ekTeRG2numuQ1vJCj-FJhj2RAhr3ek326L0MM88c5CKKRWh8saYQ4kPS7vM-JezNLWoJgxRGCmbqEDNeLQN7VlMrY32FyuhhQteuxlIDY-galJ&new=1