如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
当前回答
Desktop Android
broofa: 1617ms 12869ms
e1: 636ms 5778ms
e2: 606ms 4754ms
e3: 364ms 3003ms
e4: 329ms 2015ms
e5: 147ms 1156ms
e6: 146ms 1035ms
e7: 105ms 726ms
guid: 962ms 10762ms
generateQuickGuid: 292ms 2961ms
- Note: 500k iterations, results will vary by browser/CPU.
对于一个解释,让我们从Brofa的代码开始:
因此,它取代 x 与任何随机六分数数字, y 与随机数据(除了强迫顶部两个比特到 10 个 RFC 特征),而 regex 不匹配 - 或 4 个字符,所以他不需要处理它们。
下一个优化是另一个经典. 因为我们只处理四个字符串的输出,让我们将字符串的数量切成一半,并在每个字符串中处理八个字符串。 这是荒谬的,因为我们仍然必须处理RFC相应的字符串位置,但它不是太困难。
编辑: http://jcward.com/UUID.js - UUID.generate()
其他回答
事实上,在非Microsoft 循环中称之为 GUID 或 UUID,只是一个 128 位数码的随机数字,而 UUID 版本号(1-5)则位于固定位置比特。
因此,当你只是在0和65535之间创建一个随机数字的集合,并编码它们时,如下:
function guid()
{
function s4()
{
return Math.floor(Math.random() * 65536).toString(16).padStart(4, '0')
} // End Function s4
return s4() + s4() + '-' + s4() + '-' + "4" + s4().substr(1) + '-' + s4() + '-' + s4() + s4() + s4();
} // End Function guid
您可以获得有效的 GUID,但由于随机实施,它不是加密安全的。
要创建一个加密安全的 GUID,您需要使用 window.crypto (或 window.msCrypto for Internet Explorer)。
这就是这样:
function cryptGuid()
{
var array = new Uint16Array(8);
(window.crypto || window.msCrypto).getRandomValues(array);
var dataView = new DataView(array.buffer);
var parts = [];
for(var i = 0; i < array.length; ++i)
{
// 0&1,2,3,4,5-7 dataView.getUint16(0-7)
if(i>1 && i<6) parts.push("-");
parts.push(dataView.getUint16(i).toString(16).padStart(4, '0'));
}
parts[5] = "4" + parts[5].substr(1);
// console.log(parts);
return parts.join('').toUpperCase();// .toLowerCase();
}
cryptGuid();
此外,您还需要决定,如果您将数字返回为下或上案字符串,某些软件需要下案字符(例如,报告服务),而其他则会产生上案字符(SQL Server)。
下面是2011年10月9日的解决方案,由用户在https://gist.github.com/982883上发表评论:
UUIDv4 = function b(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,b)}
这实现了与当前最高评级的答案相同的目标,但在50比以更少的比特中,利用强迫性、回报性和曝光性评级。
UUIDv4 =
function b(
a // placeholder
){
return a // if the placeholder was passed, return
? ( // a random number from 0 to 15
a ^ // unless b is 8,
Math.random() // in which case
* 16 // a random number from
>> a/4 // 8 to 11
).toString(16) // in hexadecimal
: ( // or otherwise a concatenated string:
[1e7] + // 10000000 +
-1e3 + // -1000 +
-4e3 + // -4000 +
-8e3 + // -80000000 +
-1e11 // -100000000000,
).replace( // replacing
/[018]/g, // zeroes, ones, and eights with
b // random hex digits
)
}
这里是一个完全不符合但非常有效的实施,以产生一个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');
根據 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)
因此,开发人员为生产环境编写代码被鼓励使用严格,良好的实施,如新模块。
来自Sagi shkedy的技术博客:
function generateGuid() {
var result, i, j;
result = '';
for(j=0; j<32; j++) {
if( j == 8 || j == 12 || j == 16 || j == 20)
result = result + '-';
i = Math.floor(Math.random()*16).toString(16).toUpperCase();
result = result + i;
}
return result;
}
还有其他方法涉及使用 ActiveX 控制,但远离这些!
我以为值得指出的是,没有GUID发电机可以保证独特的钥匙(查看维基百科文章)。总是有冲突的可能性。