我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文接受一下使用node的随机id库uuid的最常见的使用方式,网上大多数教程里面,都是使用uuid生成循环domkey的。实际上,react官方并不推荐这么做,它们认为这是不科学的,key只能由被循环体本身来生成。

组件的key不是由uuid()生成的!不科学!官方不推荐!uuid()不是来干这个事情的!

苏南大叔:nodejs教程,如何使用uuid库生成五个版本的随机id? - nodejs-uuid
nodejs教程,如何使用uuid库生成五个版本的随机id?(图7-1)

苏南大叔的平行空间笔记本博客,这里记录uuid的最基本使用方式。测试环境:node@16.14.2uuid@9.0.0

安装uuid

uuid官方地址是:

苏南大叔:nodejs教程,如何使用uuid库生成五个版本的随机id? - uuid-github
nodejs教程,如何使用uuid库生成五个版本的随机id?(图7-2)

安装方式是:

npm i uuid --save

值得一提的是:uuid这个库,支持es module,也支持commonjs。也就是说,可以import(),也可以require()。比如下面两种写法都是对的,但是运行方式不同,具体可以参考:

import * as uuid from 'uuid';
// console.log(uuid.v4());

或者:

const uuid = require('uuid');
// console.log(uuid.v4());

第四版uuid【最常见】

uuid目前提供了5个版本的生成方式。其中,最为常见的是第四种方式:

import { v4 as uuidv4 } from 'uuid';
console.log(uuidv4()); 

或者:

const { v4: uuidv4 } = require('uuid');
console.log(uuidv4()); 

输出的类似:

e711f5b2-951c-4b9f-bed8-d067708f7aca

苏南大叔:nodejs教程,如何使用uuid库生成五个版本的随机id? - uuid-v4
nodejs教程,如何使用uuid库生成五个版本的随机id?(图7-3)

不要认为uuid.v4()不会生成重复的随机id。官方已经承认,会发生碰撞。

第五版uuid【也许更先进】

第五版的uuid,增加了个namespace的概念,算法是sha1,据说可以解决v4中存在的碰撞问题。第五版函数更像是一个对字符串的不可逆的加密过程,而且在字符串和namespace(其实就是一个已知不变的uuid)不变的情况下,结果也保持不变。

个人认为:还是uuid.v4()来的实在一些,直接随机个未知的uuid字符串。这也许就是第四版受到欢迎的原因。

下面的是个例子:

import * as uuid from 'uuid';
// let namespace = "9a576f06-e9e4-4a3f-ab58-abde582f79c9";
let namespace = uuid.v5.URL;
const v5 = uuid.v5('hola', namespace);

苏南大叔:nodejs教程,如何使用uuid库生成五个版本的随机id? - uuid-v5
nodejs教程,如何使用uuid库生成五个版本的随机id?(图7-4)

第五版(包括第三版)的真相就是:用一个uuid去加密一个字符串,得到另外一个不可逆但保持不变的uuid

前三个版本的uuid

实际上v2版本不存在,所以实际上是两个版本:v1(类似v4)和v3(类似v5)。

import * as uuid from 'uuid';
let v1 = uuid.v1();
let v4 = uuid.v4();
// let v2 = uuid.v2();
let v3 = uuid.v3("苏南大叔", uuid.v3.URL);
let v5 = uuid.v5("苏南大叔", uuid.v5.URL);

苏南大叔:nodejs教程,如何使用uuid库生成五个版本的随机id? - v1-v5
nodejs教程,如何使用uuid库生成五个版本的随机id?(图7-5)

v3.URLv5.URLv3.DNSv5.DNS

不管写的是URL还是DNS,都不是大家所理解的那个URLDNS。在v3版本和v5版本里面都存在。实际上还是个uuid,不过是具有特殊意义的uuid。测试代码:

import * as uuid from 'uuid';
console.log("v3.url",uuid.v3.URL);
console.log("v5.url",uuid.v5.URL);
console.log("v3.dns",uuid.v3.DNS);
console.log("v5.dns",uuid.v5.DNS);

输出:

v3.url 6ba7b811-9dad-11d1-80b4-00c04fd430c8
v5.url 6ba7b811-9dad-11d1-80b4-00c04fd430c8
v3.dns 6ba7b810-9dad-11d1-80b4-00c04fd430c8
v5.dns 6ba7b810-9dad-11d1-80b4-00c04fd430c8

而且在测试中,这四个值输出都是一致的。所以,暂时不确定其具体逻辑。等待后续有需要的时候再研究。

检验uuid版本号

一二三号版本的uuid,可能使用的概率非常低,苏南大叔就暂时不写了。最常见的是v4,更先进的是v5。苏南大叔的理解下:

  • v1是个基于时间算法的uuid
  • v2版本已经消失了,根本不存在。
  • v3算法是基于md5的,和v5版本基本就是一样一样的,就是算法不一样,多次加密的结果也一致。
  • v4是随机个字符串,每次结果都不一致。但是,据官方承认,会随机到相同的结果,只是概率很低。
  • v5能做到uuid的唯一性,多次加密结果一致。

确定uuid字符串的版本号,也就是说确定uuid是通过第几版方法生成的。因为对于uuidVersion()来说,对于一个异常字符串的检验,会抛出异常信息throw TypeError('Invalid UUID');。所以,两个函数最好组合一下。

可以使用下面的方法:

import * as uuid from 'uuid';

let v_ = "苏南大叔";
let v1 = "1ae2acc0-6d8e-11ed-99db-e1a1a6307582";
let v3 = "378e476d-4eb2-35b0-ace8-5bbe25f24385";
let v4 = "61be160e-9bec-48c8-9f0b-587d767f5c11";
let v5 = "ae5d081b-6aa9-5d96-a20f-1316a6444b7b";

// console.log(v_, uuidVersion(v_));  // throw TypeError('Invalid UUID');
console.log(v_, checkVersion(v_));
console.log(v1, checkVersion(v1));
console.log(v3, checkVersion(v3));
console.log(v4, checkVersion(v4));
console.log(v5, checkVersion(v5));
console.log(uuid.NIL, checkVersion(uuid.NIL));
console.log(uuid.v5.URL, checkVersion(uuid.v5.URL));
console.log(uuid.v5.DNS, checkVersion(uuid.v5.DNS));

function checkVersion(_uuid) {
    if (uuid.validate(_uuid)) {
        return uuid.version(_uuid);
    }
    return "-";
}

uuid.NIL是个特殊的值,00000000-0000-0000-0000-000000000000,版本号居然是0

苏南大叔:nodejs教程,如何使用uuid库生成五个版本的随机id? - 版本检测2
nodejs教程,如何使用uuid库生成五个版本的随机id?(图7-6)

字节与字符串互转

uuid称自己为string,它还有一种bytes的表达形式。两者可以相互转换。(说实话好像没啥用)

import * as uuid from 'uuid';
let v5 = uuid.v5.URL;
let bytes = uuid.parse(v5);
let v5_ = uuid.stringify(bytes);
console.log(v5);
console.log(bytes);
console.log(v5_);
  • uuid.parse(),字符串转字节。
  • uuid.stringify(),字节转字符串。

苏南大叔:nodejs教程,如何使用uuid库生成五个版本的随机id? - 字节转字符串
nodejs教程,如何使用uuid库生成五个版本的随机id?(图7-7)

更多使用方式

更多的uuid文档,可以参考官方文档:

结束语

uuid()key,苏南大叔觉得理论上来说,可行。但是,react官方认为并不合适。那么,就用uuid()做点别的事情吧。更多node经验文章,请点击:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   node