如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
当前回答
基于布罗法的答案,我有自己的答案:
这里是使用 crypto.getRandomValues 的加密更强的版本。
函数 uuidv4() { const a = crypto.getRandomValues(新 Uint16Array(8)); let i = 0; return '00-0-4-1-000'.replace(/[^-]/g, s => (a[i++] + s * 0x10000 >> s).toString(16).padStart(4, '0') ); } console.log(uuidv4());
这里是使用 Math.random 的更快版本,使用几乎相同的原则:
函数 uuidv4() { return '00-0-4-1-000'.replace(/[^-]/g, s => ((Math.random() + ~~s) * 0x10000 >> s).toString(16).padStart(4, '0') ); } console.log(uuidv4());
其他回答
只有在任何人落下谷歌正在寻找一个小用途图书馆的情况下,ShortId满足了这个问题的所有要求,它允许指定允许的字符和长度,并保证不序列,不重复的线条。
为了使这一点更为真实的答案,该图书馆的核心使用下列逻辑来制作其简短的ID:
function encode(lookup, number) {
var loopCounter = 0;
var done;
var str = '';
while (!done) {
str = str + lookup( ( (number >> (4 * loopCounter)) & 0x0f ) | randomByte() );
done = number < (Math.pow(16, loopCounter + 1 ) );
loopCounter++;
}
return str;
}
/* Generates the short id */
function generate() {
var str = '';
var seconds = Math.floor((Date.now() - REDUCE_TIME) * 0.001);
if (seconds === previousSeconds) {
counter++;
} else {
counter = 0;
previousSeconds = seconds;
}
str = str + encode(alphabet.lookup, version);
str = str + encode(alphabet.lookup, clusterWorkerId);
if (counter > 0) {
str = str + encode(alphabet.lookup, counter);
}
str = str + encode(alphabet.lookup, seconds);
return str;
}
我没有编辑这只是反映这个方法的最基本部分,所以上面的代码包含一些额外的逻辑从图书馆. 如果你对它正在做的一切好奇,请看看来源: https://github.com/dylang/shortid/tree/master/lib
const uuid = url => url.substr(-36);
上述将与创建ObjectURL的任何合适的实施工作,因为规格明确要求 UUID 添加到前者返回的 URL 的结尾。
要清楚,有时 - 点击,也许大部分时间,所有考虑 - 你想生成一个 UUID 别的东西,而不是资源,你创建的 URL 与创建ObjectURL. 在这些情况下,呼叫后一个方法在一些新的 Blob() 将绝对坦克的性能(和泄漏的记忆,除非你清理后自己使用相应的 revokeObjectURL)。
我不建议您使用上述方法仅为创建UUID,除非您已经通过创建ObjectURL获得的URL或最终具有UUID的东西。
我只是想提到上述版本的完整性。
这个报价返回 5 组 8 个数字从 a-z,0-9 大多数是随机的,但包含日时,并且有一个随机增加的计算器. 你可以指定任何基础你喜欢(六,十,36),默认选择一个随机基础为每个组的 8,在基础范围 16 到 36
function newId(base) { return[ Math.random, function (){ return (newId.last ? windowId.last + Math.random() : Math.random() ) }, Math.random, Date.now, Math.random ].map(function(fn){ return fn().toString(base||(16+(Math.random()*20))).substr(-8); }).join('-'); } var demo = function(base){ document.getElementById('uuid').textContent = newId(base); } demo(16); #uuid { font-family: monospace; font-size: 1.5em; } <p id="uuid"></p> <button onclick="demo(16);">Hex (base 16)</button> <button onclick="demo(36);">Base 36</button> <button onclick="demo(10);">Decimal (base 10)</button> <button onclick="demo();">Random base</button>
ES6 样品
const guid=()=> {
const s4=()=> Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
return `${s4() + s4()}-${s4()}-${s4()}-${s4()}-${s4() + s4() + s4()}`;
}
[编辑 2021-10-16 以反映 RFC4122 符合 UUID 的最新最佳做法]
大多数读者在这里会想使用 uuid 模块,它已被测试和支持。
如果其中没有一个为您工作,则有这个方法(基于这个问题的原始答案):函数 uuidv4() {返回([1e7]+-1e3+-4e3+-8e3+-1e11)。代替(/[018]/g,c =>(c ^ crypto.getRandomValues(新Uint8Array(1))[0] & 15 >> c / 4).toString(16) ; } console.log(uuidv4());
注意:依靠 Math.random() 的任何 UUID 发电机的使用是由于这里最好的解释而受到强烈的拒绝(包括此答案的以前版本中显示的剪辑) TL;DR:基于 Math.random() 的解决方案不提供良好的独特性保证。