JS获取UUID及其它随机字符串

前言

开发过程中我们可能需要一些不重复的数字或字符串,根据使用场景的不同我们可以使用不同的方式。

UUID

在JavaScript中,原生的API并没有直接提供生成UUID(Universally Unique Identifier,通用唯一识别码)的方法。

但是,你可以使用一些第三方库来生成UUID,或者编写一个简单的函数来生成。

UUID库

如果你希望使用第三方库,uuid 是一个流行的选择。

你可以通过npm或yarn来安装它:

1
2
3
npm install uuid
# 或者
yarn add uuid

然后在你的代码中这样使用:

1
2
3
4
import { v4 as uuidv4 } from 'uuid';

const myUUID = uuidv4();
console.log(myUUID); // 输出一个UUID,例如:'1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'

简单函数生成

如果你不想使用外部库,也可以通过编写一个简单的函数来生成UUID,尽管这种方法可能不会生成完全符合RFC 4122标准的UUID。

以下是一个简单的UUID生成函数的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function generateUUID() {
let d = new Date().getTime();
if (window.performance && typeof window.performance.now === "function") {
d += performance.now(); // 使用高精度时间戳
}
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
});
return uuid;
}

const myUUID = generateUUID();
console.log(myUUID); // 输出一个类似UUID的字符串

请注意,这个简单的函数生成的UUID可能与RFC 4122标准不完全一致,特别是在版本和变体字段上,但它对于许多应用程序来说可能已经足够了。

如果你需要严格符合标准的UUID,建议使用uuid库。

crypto

现代浏览器和Node.js环境中提供了 crypto 模块,可以生成更高质量的随机数,确保生成的UUID具有更好的唯一性。具体有两种方式:

使用 crypto.randomUUID()(现代浏览器支持):
如果目标环境支持,这是最简单且符合RFC 4122标准的方式:

1
const uuid = crypto.randomUUID();

使用 crypto.getRandomValues()
对于不支持 crypto.randomUUID() 的较旧环境,可以使用 getRandomValues() 方法配合Uint8Array生成UUID:

1
2
3
4
5
6
7
function generateUUID() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}

const uuid = generateUUID();

两者结合

优化后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function generateUUID () {
if (typeof crypto === 'object') {
if (typeof crypto.randomUUID === 'function') {
return crypto.randomUUID();
}
if (typeof crypto.getRandomValues === 'function' && typeof Uint8Array === 'function') {
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
}
}
let d = new Date().getTime();
if (window.performance && typeof window.performance.now === "function") {
d += performance.now(); // 使用高精度时间戳
}
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
});
return uuid;
};

时间戳

不太适用与保证唯一的地方,但是比如页面添加参数来禁用缓存的时候可以使用时间戳。

毫秒

在 JavaScript 中,你可以使用 Date.now() 方法来获取当前的时间戳。

它返回自 1970 年 1 月 1 日 00:00:00 UTC(协调世界时)以来经过的毫秒数。

以下是一个示例:

1
2
var timestamp = Date.now();
console.log(timestamp);

这将在控制台输出当前的时间戳。

要获取当前的时间戳(以秒为单位),你可以使用 Math.floor() 函数将毫秒时间戳除以 1000 并向下取整。

下面是一个示例:

1
2
var timestampInSeconds = Math.floor(Date.now() / 1000);
console.log(timestampInSeconds);

这将输出当前的时间戳(以秒为单位)到控制台。请注意,Date.now() 返回的是当前的毫秒时间戳,通过除以 1000 并向下取整,可以将其转换为以秒为单位的时间戳。

时间戳+随机字符串

基本也能保证唯一,并且好处在于前8位是按照时间排序的,性能相比于UUID会高一点。

不适用于要保证完全唯一的场景。

1
2
3
function getRandomStr(){
return Date.now().toString(36)+Math.random().toString(36).substring(2, 10);
}

测试一下

1
2
3
4
5
let mSet = new Set();;
for(let i=0;i<10000;i++){
mSet.add(getRandomStr());
}
console.info(mSet.size);

我这里测试了一万次基本上不会重复。