如何在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 ) 并获得八个六分数字符的序列。
链接到我的博客上的这篇文章
享受吧:)
其他回答
这里有很多正确的答案,但不幸的是,包含的代码样本是相当密码和难以理解的。
请注意,随后的代码使用二进制字母以提高可读性,因此需要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。
最后笔记
此外,有很多第三方包. 但是,只要你只是基本的需求,我不推荐它们. 事实上,没有很多赢得和几乎失去。 作者可以追求最薄的比特的性能,“修复”的事情,不应该固定,当涉及到安全,这是一个危险的想法. 同样,他们可能会引入其他错误或不一致性。
根據 RFC 4122 的 UUID (Universally Unique IDentifier),也被稱為 GUID (Globally Unique IDentifier),是為提供某些獨特性保證而設計的識別。
虽然可以在JavaScript代码的几个行中实施符合RFC的UUID(例如,请参见 @broofa的答案,下面),但有几个常见的漏洞:
无效 ID 格式(UUID 必须是“xxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx”的格式,其中 x 是 [0-9, a-f] M 是 [1-5] 的格式,而 N 是 [8, 9, a 或 b] 使用低质量的随机性来源(如 Math.random)
因此,开发人员为生产环境编写代码被鼓励使用严格,良好的实施,如新模块。
还有另一种方式来做同样的事情:
function guid() {
var chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
var str = "";
for(var i=0; i<36; i++) {
var str = str + ((i == 8 || i == 13 || i == 18 || i == 23) ? "-" : chars[Math.floor(Math.random()*chars.length)]);
};
return str;
}
重要的是要使用精心测试的代码,由多个参与者保持,而不是为此擦干自己的东西。
这是一个地方,你可能想偏好最稳定的代码,而不是最短的可能的智能版本,在X浏览器工作,但不考虑到Y的偶像合并,这往往会导致非常硬的调查错误,而不是只随机表现给一些用户。
这个是基于日期,并添加一个随机的补充到“保证”的独特性。
它很好地用于CSS识别器,总是返回类似的东西,并且很容易被黑客攻击:
uid-139410573297741
var getUniqueId = function (prefix) {
var d = new Date().getTime();
d += (parseInt(Math.random() * 100)).toString();
if (undefined === prefix) {
prefix = 'uid-';
}
d = prefix + d;
return d;
};