如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
当前回答
这个应用程序的100万次执行只需要32.5秒,这是我从未在浏览器中看到的最快(唯一的解决方案没有漏洞/漏洞)。
/**
* Generates a GUID string.
* @returns {string} The generated GUID.
* @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
* @author Slavik Meltser.
* @link http://slavik.meltser.info/?p=142
*/
function guid() {
function _p8(s) {
var p = (Math.random().toString(16)+"000000000").substr(2,8);
return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
}
return _p8() + _p8(true) + _p8(true) + _p8();
}
console.time('t');
for (var i = 0; i < 10000000; i++) {
guid();
};
console.timeEnd('t');
算法:
Math.random() 函数返回 0 和 1 之间的十数数,在十数分数点(例如 0.4363923368509859 )之后有 16 个数字。 然后我们采取这个数字并将其转换为 16 个基线(从上面的示例中,我们将获得 0.6fb7687f)。 Math.random(.toString(16 ) 然后我们切断了 0 个预定(.0.6fb7687f => 6fb7687f ) 并获得八个六分数字符的序列。
链接到我的博客上的这篇文章
享受吧:)
其他回答
不要使用 Math.random 在任何情况下,因为它产生一个非加密的随机数字来源。
下面的解决方案使用crypto.getRandomValues
function uuidv4() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
// tslint:disable-next-line: no-bitwise
const r =
(window.crypto.getRandomValues(new Uint32Array(1))[0] *
Math.pow(2, -32) * 16) |
0;
// tslint:disable-next-line: no-bitwise
const v = c === "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
此链接有助于您了解由 Fortify Scanner 投下的不安全的随机性。
这里有很多正确的答案,但不幸的是,包含的代码样本是相当密码和难以理解的。
请注意,随后的代码使用二进制字母以提高可读性,因此需要ECMAScript 6。
Node.js 版本
function uuid4() {
let array = new Uint8Array(16)
crypto.randomFillSync(array)
// Manipulate the 9th byte
array[8] &= 0b00111111 // Clear the first two bits
array[8] |= 0b10000000 // Set the first two bits to 10
// Manipulate the 7th byte
array[6] &= 0b00001111 // Clear the first four bits
array[6] |= 0b01000000 // Set the first four bits to 0100
const pattern = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
let idx = 0
return pattern.replace(
/XX/g,
() => array[idx++].toString(16).padStart(2, "0"), // padStart ensures a leading zero, if needed
)
}
浏览器版本
只有第二条线是不同的。
function uuid4() {
let array = new Uint8Array(16)
crypto.getRandomValues(array)
// Manipulate the 9th byte
array[8] &= 0b00111111 // Clear the first two bits
array[8] |= 0b10000000 // Set the first two bits to 10
// Manipulate the 7th byte
array[6] &= 0b00001111 // Clear the first four bits
array[6] |= 0b01000000 // Set the first four bits to 0100
const pattern = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
let idx = 0
return pattern.replace(
/XX/g,
() => array[idx++].toString(16).padStart(2, "0"), // padStart ensures a leading zero, if needed
)
}
测试
最后,相应的测试(Jasmine)。
describe(".uuid4()", function() {
it("returns a UUIDv4 string", function() {
const uuidPattern = "XXXXXXXX-XXXX-4XXX-YXXX-XXXXXXXXXXXX"
const uuidPatternRx = new RegExp(uuidPattern.
replaceAll("X", "[0-9a-f]").
replaceAll("Y", "[89ab]"))
for (let attempt = 0; attempt < 1000; attempt++) {
let retval = uuid4()
expect(retval.length).toEqual(36)
expect(retval).toMatch(uuidPatternRx)
}
})
})
UUID v4 解释
非常好的解释 UUID 版本 4 在这里: 创建一个符合 RFC 4122 的 UUID。
最后笔记
此外,有很多第三方包. 但是,只要你只是基本的需求,我不推荐它们. 事实上,没有很多赢得和几乎失去。 作者可以追求最薄的比特的性能,“修复”的事情,不应该固定,当涉及到安全,这是一个危险的想法. 同样,他们可能会引入其他错误或不一致性。
最简单的功能来做到这一点:
function createGuid(){
let S4 = () => Math.floor((1+Math.random())*0x10000).toString(16).substring(1);
let guid = `${S4()}${S4()}-${S4()}-${S4()}-${S4()}-${S4()}${S4()}${S4()}`;
return guid.toLowerCase();
}
如果您只需要任何特定格式的随机 128 位序列,您可以使用:
function uuid() {
return crypto.getRandomValues(new Uint32Array(4)).join('-');
}
这将返回像2350143528-4164020887-938913176-2513998651这样的东西。
OK,使用 uuid 包,并支持版本 1, 3, 4 和 5 UUID,做:
yarn add uuid
然后:
const uuidv1 = require('uuid/v1');
uuidv1(); // ⇨ '45745c60-7b1a-11e8-9c9c-2d42b21b1a3e'
您也可以使用完整的选项:
const v1options = {
node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],
clockseq: 0x1234,
msecs: new Date('2011-11-01').getTime(),
nsecs: 5678
};
uuidv1(v1options); // ⇨ '710b962e-041c-11e1-9234-0123456789ab'
要了解更多信息,请参阅 npm 页面。