如何在JavaScript中创建GUID(全局唯一标识符)?GUID / UUID应至少为32个字符,并应保持在ASCII范围内,以避免在传递时出现问题。
我不确定所有浏览器都可用哪些例程,内置的随机数生成器有多“随机”和有多少种子等信息。
如何在JavaScript中创建GUID(全局唯一标识符)?GUID / UUID应至少为32个字符,并应保持在ASCII范围内,以避免在传递时出现问题。
我不确定所有浏览器都可用哪些例程,内置的随机数生成器有多“随机”和有多少种子等信息。
如果您的环境是 SharePoint,那么有一个名为 SP.Guid.newGuid
的实用函数 (MSDN 链接) 可以创建一个新的 GUID。此函数位于 sp.init.js 文件中。如果您重写此函数(以删除其他私有函数的某些依赖项),则它应该如下所示:
var newGuid = function () {
var result = '';
var hexcodes = "0123456789abcdef".split("");
for (var index = 0; index < 32; index++) {
var value = Math.floor(Math.random() * 16);
switch (index) {
case 8:
result += '-';
break;
case 12:
value = 4;
result += '-';
break;
case 16:
value = value & 3 | 8;
result += '-';
break;
case 20:
result += '-';
break;
}
result += hexcodes[value];
}
return result;
};
这个基于日期,加了随机后缀以“确保”唯一性。
它对于CSS标识符很有效,总是返回类似uid-139410573297741的东西,并且易于被黑客攻击:
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;
};
受到broofa的回答的启发,我有自己的看法:
这是使用crypto.getRandomValues
的密码学更强版本。
function uuidv4() {
const a = crypto.getRandomValues(new 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
的更快版本,原理几乎相同:
function uuidv4() {
return '00-0-4-1-000'.replace(/[^-]/g,
s => ((Math.random() + ~~s) * 0x10000 >> s).toString(16).padStart(4, '0')
);
}
console.log(uuidv4());
好的,使用 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页面。
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();
}
基于crypto
API的 TypeScript 版本,参考自 broofa在2017-06-28更新的版本:
function genUUID() {
// Reference: https://dev59.com/7HVD5IYBdhLWcg3wDXF3#2117523
return ("10000000-1000-4000-8000-100000000000").replace(/[018]/g, s => {
const c = Number.parseInt(s, 10)
return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
})
}
原因:
number[]
和 number
之间使用 +
是无效的。string
转换为 number
必须是显式的。return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> c / 4)).toString(16);
。 - Willster使用经过多人维护的、经过充分测试的代码非常重要,而不是为此编写自己的代码。
这可能是你更喜欢最稳定的代码而不是最短的 clever 版本的地方,尽管它可以在 X 浏览器中工作,但它并没有考虑到 Y 的特殊情况,这经常会导致只针对某些用户随机出现的非常难以调查的错误。个人建议使用位于 https://github.com/aurigadl/uuid-js 的 uuid-js,该库支持 Bower,因此可以轻松更新。
这里有许多正确的答案,但遗憾的是,包含的代码示例相当晦涩难懂。以下是我创建版本4(随机)UUID的方式。
请注意,以下代码片段使用二进制字面量以提高可读性,因此需要ECMAScript 6。
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版本4的很好的解释在这里:生成符合RFC 4122标准的UUID。
此外,有很多第三方包。但是,只要您只有基本需求,我不建议使用它们。真的没有多少可赢的,却有很多可失去的。作者可能追求最微小的性能提升,"修复"本来不应该修复的问题,涉及到安全时,这是一个有风险的想法。同样,他们可能会引入其他错误或不兼容性。谨慎地更新需要时间。
生成唯一标识的简单方法是使用时间戳,并在其后加上随机数。我喜欢在前面加上“uuid-”。
下面的函数将生成类型为uuid-14d93eb1b9b4533e6的随机字符串。在此情况下,无需生成32个字符的随机字符串。一个16个字符的随机字符串已经足够提供JavaScript中的唯一UUID。
var createUUID = function() {
return "uuid-" + ((new Date).getTime().toString(16) + Math.floor(1E7*Math.random()).toString(16));
}
BigInt
和ES6类以及其他技术,可以实现每秒500,000个uuid的速率。参见参考链接 - smallscriptURL.createObjectURL(new Blob()).substr(-36)
即可。该方法得到了很好的浏览器支持。为避免内存泄漏,需要调用URL.revokeObjectURL(url)
。 - rinogo