nodejs教程,如何使用uuid库生成五个版本的随机id?
发布于 作者:苏南大叔 来源:程序如此灵动~本文接受一下使用node
的随机id库uuid
的最常见的使用方式,网上大多数教程里面,都是使用uuid
生成循环dom
的key
的。实际上,react
官方并不推荐这么做,它们认为这是不科学的,key
只能由被循环体本身来生成。
组件的key
不是由uuid()
生成的!不科学!官方不推荐!uuid()
不是来干这个事情的!
苏南大叔的程序如此灵动博客,这里记录uuid
的最基本使用方式。测试环境:node@16.14.2
,uuid@9.0.0
。
安装uuid
库
uuid
官方地址是:
安装方式是:
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
不要认为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);
第五版(包括第三版)的真相就是:用一个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);
v3.URL
、v5.URL
、v3.DNS
、v5.DNS
不管写的是URL
还是DNS
,都不是大家所理解的那个URL
和DNS
。在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
。
字节与字符串互转
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()
,字节转字符串。
更多使用方式
更多的uuid
文档,可以参考官方文档:
结束语
用uuid()
做key
,苏南大叔觉得理论上来说,可行。但是,react
官方认为并不合适。那么,就用uuid()
做点别的事情吧。更多node
经验文章,请点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。