Starting from Chome92 version, crypto module already supports randomUUID()
method.
1. The old way
In front-end web, we usually use timestamp or Math.random() when generating a uuid. For example, on stackoverflow, there is a famous code: How to create a GUID / UUID, which is generated by Math.random()
.
1
2
3
4
5
6
7
8
9
|
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
console.log(uuidv4()); // "f94adc58-89b7-4c70-bc92-2935ea6fb5d2" 格式一样,但每次都不一样
|
The random() method is called once for each position.
2. randomUUID
Chrome now has native support for the uuId method, crypto.randomUUID()
, starting with version 92.
This randomUUID()
method can be used in the future when you want to get a random value, or to identify a device (under less demanding conditions).
3. Summary
randomUUID(), a browser-provided native, does work well and conforms to the v4 version of the format.
But there is one drawback: compatibility is too poor. Not only is it not supported by other browsers, but even in Chrome, it is only available from version 92 onwards.
But I believe other browsers will support this method in the near future.
Let’s write a front-end method to get uuid.
- use crypto.randomUUID as a preference.
- if not, use preferentially use crypto.getRandomValues.
- use Math.random() for underwriting.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
const generateUUID = () => {
if (typeof crypto === 'object') {
if (typeof crypto.randomUUID === 'function') {
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID
return crypto.randomUUID();
}
if (typeof crypto.getRandomValues === 'function' && typeof Uint8Array === 'function') {
// https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid
const callback = (c) => {
const num = Number(c);
return (num ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (num / 4)))).toString(16);
};
return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, callback);
}
}
let timestamp = new Date().getTime();
let perforNow = (typeof performance !== 'undefined' && performance.now && performance.now() * 1000) || 0;
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
let random = Math.random() * 16;
if (timestamp > 0) {
random = (timestamp + random) % 16 | 0;
timestamp = Math.floor(timestamp / 16);
} else {
random = (perforNow + random) % 16 | 0;
perforNow = Math.floor(perforNow / 16);
}
return (c === 'x' ? random : (random & 0x3) | 0x8).toString(16);
});
};
|