如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
当前回答
我已经建立在这里提到的所有东西,以产生两倍的速度,可携带的所有环境,包括节点,并从Math.random()升级到加密强度的随机性。
function random() {
const
fourBytesOn = 0xffffffff, // 4 bytes, all 32 bits on: 4294967295
c = typeof crypto === "object"
? crypto // Node.js or most browsers
: typeof msCrypto === "object" // Stinky non-standard Internet Explorer
? msCrypto // eslint-disable-line no-undef
: null; // What old or bad environment are we running in?
return c
? c.randomBytes
? parseInt(c.randomBytes(4).toString("hex"), 16) / (fourBytesOn + 1) - Number.EPSILON // Node.js
: c.getRandomValues(new Uint32Array(1))[0] / (fourBytesOn + 1) - Number.EPSILON // Browsers
: Math.random();
}
function uuidV4() { // eslint-disable-line complexity
// If possible, generate a single random value, 128 bits (16 bytes)
// in length. In an environment where that is not possible, generate
// and make use of four 32-bit (4-byte) random values.
// Use crypto-grade randomness when available, else Math.random()
const
c = typeof crypto === "object"
? crypto // Node.js or most browsers
: typeof msCrypto === "object" // Stinky non-standard Internet Explorer
? msCrypto // eslint-disable-line no-undef
: null; // What old or bad environment are we running in?
let
byteArray = c
? c.randomBytes
? c.randomBytes(16) // Node.js
: c.getRandomValues(new Uint8Array(16)) // Browsers
: null,
uuid = [ ];
/* eslint-disable no-bitwise */
if ( ! byteArray) { // No support for generating 16 random bytes
// in one shot -- this will be slower
const
int = [
random() * 0xffffffff | 0,
random() * 0xffffffff | 0,
random() * 0xffffffff | 0,
random() * 0xffffffff | 0
];
byteArray = [ ];
for (let i = 0; i < 256; i++) {
byteArray[i] = int[i < 4 ? 0 : i < 8 ? 1 : i < 12 ? 2 : 3] >> i % 4 * 8 & 0xff;
}
}
byteArray[6] = byteArray[6] & 0x0f | 0x40; // Always 4, per RFC, indicating the version
byteArray[8] = byteArray[8] & 0x3f | 0x80; // Constrained to [89ab], per RFC for version 4
for (let i = 0; i < 16; ++i) {
uuid[i] = (byteArray[i] < 16 ? "0" : "") + byteArray[i].toString(16);
}
uuid =
uuid[ 0] + uuid[ 1] + uuid[ 2] + uuid[ 3] + "-" +
uuid[ 4] + uuid[ 5] + "-" +
uuid[ 6] + uuid[ 7] + "-" +
uuid[ 8] + uuid[ 9] + "-" +
uuid[10] + uuid[11] + uuid[12] + uuid[13] + uuid[14] + uuid[15];
return uuid;
/* eslint-enable no-bitwise */
}
其他回答
我们可以使用代替和crypto.getRandomValues以获得这样的输出:
xxxxxxxxxxxxxxxxxxxxxxx
此分類上一篇
如果我们正在寻找一个 opti 解决方案,我们必须用一个序列(32 )取代 crypto.getRandomValues(新 Uint8Array(1))[0]。
const uuidv4 = () =>
([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
console.log(uuidv4());
要得到这个代码:
函数 uuidv4() { 让比特 = window.crypto.getRandomValues(新 Uint8Array(32)); const randomBytes = () => (比特 = bytes.slice(1)) && bytes[0]; 返回([1e7] + -1e3 + -4e3 + -8e3 + -1e11); 取代(/[018]/g, c => (c ^ randomBytes() & 15 >> c / 4).toString(16) ; } for (var i = 0; i < 10; i++) console.log(uuidv4());
碰撞:
我们可以喜欢谷歌分析,并添加一个时间标签: uuidv4() + "。
这个应用程序的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 ) 并获得八个六分数字符的序列。
链接到我的博客上的这篇文章
享受吧:)
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()
这创建了一个版本 4 UUID (创建于假冒随机数字):
function uuid()
{
var chars = '0123456789abcdef'.split('');
var uuid = [], rnd = Math.random, r;
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4'; // version 4
for (var i = 0; i < 36; i++)
{
if (!uuid[i])
{
r = 0 | rnd()*16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
}
}
return uuid.join('');
}
下面是产生的 UUID 的样本:
682db637-0f31-4847-9cdf-25ba9613a75c
97d19478-3ab2-4aa1-b8cc-a1c3540f54aa
2eed04c9-2692-456d-a0fd-51012f947136
这里是一个完全不符合但非常有效的实施,以产生一个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');