如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
当前回答
这里是一个完全不符合但非常有效的实施,以产生一个ASCII安全的GUID类似的独特识别器。
function generateQuickGuid() {
return Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
}
创建 26 个字符 [a-z0-9],产生一个 UID 既较短又比 RFC 符合的 GUID 更独特。
这里是这个功能的使用例子和时间表,以及这个问题的其他几个答案。
>>> generateQuickGuid()
"nvcjf1hs7tf8yyk4lmlijqkuo9"
"yq6gipxqta4kui8z05tgh9qeel"
"36dh5sec7zdj90sk2rx7pjswi2"
runtime: 32.5s
>>> GUID() // John Millikin
"7a342ca2-e79f-528e-6302-8f901b0b6888"
runtime: 57.8s
>>> regexGuid() // broofa
"396e0c46-09e4-4b19-97db-bd423774a4b3"
runtime: 91.2s
>>> createUUID() // Kevin Hakanson
"403aa1ab-9f70-44ec-bc08-5d5ac56bd8a5"
runtime: 65.9s
>>> UUIDv4() // Jed Schmidt
"f4d7d31f-fa83-431a-b30c-3e6cc37cc6ee"
runtime: 282.4s
>>> Math.uuid() // broofa
"5BD52F55-E68F-40FC-93C2-90EE069CE545"
runtime: 225.8s
>>> Math.uuidFast() // broofa
"6CB97A68-23A2-473E-B75B-11263781BBE6"
runtime: 92.0s
>>> Math.uuidCompact() // broofa
"3d7b7a06-0a67-4b67-825c-e5c43ff8c1e8"
runtime: 229.0s
>>> bitwiseGUID() // jablko
"baeaa2f-7587-4ff1-af23-eeab3e92"
runtime: 79.6s
>>>> betterWayGUID() // Andrea Turri
"383585b0-9753-498d-99c3-416582e9662c"
runtime: 60.0s
>>>> UUID() // John Fowler
"855f997b-4369-4cdb-b7c9-7142ceaf39e8"
runtime: 62.2s
这里是时间代码。
var r;
console.time('t');
for (var i = 0; i < 10000000; i++) {
r = FuncToTest();
};
console.timeEnd('t');
其他回答
对于我的使用案例,我需要 ID 世代,保证在全球范围内是独一无二的;没有例外.我与问题斗争了一段时间,并提出了一个名为 TUID (真正独一无二的 ID ) 的解决方案。
对于那些在Windows上使用JavaScript的人(例如,Windows Script Host(WSH),CScript,和HTA)。一个可以使用ActiveX。
WScript.Echo((new ActiveXObject("Scriptlet.TypeLib")).Guid)
请注意,这个答案仅适用于我列出的技术,它不会在任何浏览器中工作,甚至不是Microsoft Edge! 因此,你的距离与这个答案不同。
根據 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)
因此,开发人员为生产环境编写代码被鼓励使用严格,良好的实施,如新模块。
这里有很多正确的答案,但不幸的是,包含的代码样本是相当密码和难以理解的。
请注意,随后的代码使用二进制字母以提高可读性,因此需要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();
}