如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
当前回答
这里是一个方法,使用真实的随机通过 random.org 生成 RFC4122 如果错误,它会回到浏览器的内置加密图书馆,这应该几乎是相同的好。
async function UUID() {
//get 31 random hex characters
return (await (async () => {
let output;
try {
//try from random.org
output = (await (
await fetch('https://www.random.org/integers/?num=31&min=0&max=15&col=31&base=16&format=plain&rnd=new')
).text())
//get rid of whitespace
.replace(/[^0-9a-fA-F]+/g, '')
;
if (output.length != 31)
throw '';
}
catch {
output = '';
try {
//failing that, try getting 16 8-bit digits from crypto
for (let num of crypto.getRandomValues(new Uint8Array(16)))
//interpret as 32 4-bit hex numbers
output += (num >> 4).toString(16) + (num & 15).toString(16);
//we only want 31
output = output.substr(1);
}
catch {
//failing THAT, use Math.random
while (output.length < 31)
output += (0 | Math.random() * 16).toString(16);
}
}
return output;
})())
//split into appropriate sections, and set the 15th character to 4
.replace(/^(.{8})(.{4})(.{3})(.{4})/, '$1-$2-4$3-$4-')
//force character 20 to the correct range
.replace(/(?<=-)[^89abAB](?=[^-]+-[^-]+$)/, (num) => (
(parseInt(num, 16) % 4 + 8).toString(16)
))
;
}
此分類上一篇
其他回答
使用:
let uniqueId = Date.now().toString(36) + Math.random().toString(36).substring(2);
document.getElementById(“独一无二”。innerHTML = Math.random().toString(36).substring(2) + (新日期()).getTime().toString(36); <div id="unique"> </div>
您可以通过添加更多数字来增加这个数字,但要创建100%独特的ID,您将需要使用全球计数器。
let u = Date.now().toString(16) + Math.random().toString(16) + '0'.repeat(16);
let guid = [u.substr(0,8), u.substr(8,4), '4000-8' + u.substr(13,3), u.substr(16,12)].join('-');
let u = Date.now().toString(16)+Math.random().toString(16)+'0'.repeat(16); let guid = [u.substr(0,8), u.substr(8,4), '4000-8' + u.substr(13,3), u.substr(16,12)].join('-'); document.getElementById("unique").innerHTML = guid; <div id="unique"> </div>
只有在任何人落下谷歌正在寻找一个小用途图书馆的情况下,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
以下是基于 RFC 4122 的某些代码,第 4.4 节(从真实随机或偏随机号创建 UUID 的算法)。
function createUUID() {
// http://www.ietf.org/rfc/rfc4122.txt
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
因此,注意到这篇文章有超过30个答案,这里是...... 这篇文章有:一个“TL;DR”代码部分w/自含的es6类 Xuid一个使用案例和动机讨论部分关于es6类 Xuid提供代码。
class Xuid {
//@ edges.sm.st, ess.dev: MIT license Smallscript/David Simmons 2020
//! Can't use `static const field = const` xbrowser (thus, const's duped)
static get v4New() {
const ns7Now = this.ns7Now, xnode48 = this.xnode48; let clock_seq13
// monotonic `clock_seq` guarantee (13-bits/time-quantum)
if(ns7Now <= this.ns7Now_prevSeq && this.ns7Now_prevSeq)
clock_seq13 = ((this.ns7Now_prevSeq += 1n) - ns7Now) & 0b1_1111_1111_1111n
else
clock_seq13 = 0n, this.ns7Now_prevSeq = ns7Now
const time60 = ((ns7Now << 4n) & 0xFFFF_FFFF_FFFF_0000n) |
(ns7Now & 0x0000_0000_0000_0FFFn),
v4 = 0x1_00000000_0000_0000_0000_000000000000n |
(time60 << 64n) | (0x00000000_0000_4000_0000_000000000000n) | // M: V4
(0b110n << 61n) | (clock_seq13 << 48n) | // N: Variant-2 time-seq collation
xnode48, s = v4.toString(16)//.substr(1)
return `{${s.substr(1,8)}-${s.substr(9,4)}-${s.substr(13,4)}-${
s.substr(17,4)}-${s.substr(21,12)}}`
}
static get xnode48()/*:<BigInt#48>*/{
if(this.xnode48_) return this.xnode48_
let clockSeqNode; if(typeof URL !== 'undefined' && URL.createObjectURL) {
const url = URL.createObjectURL(new Blob())
const id = (url.toString().split('/').reverse()[0]).split('-')
URL.revokeObjectURL(url)
clockSeqNode = BigInt('0x'+id[3]+id[4])
}
else {
const a4 = this.a4; this.getRandomValues(this.a4);
clockSeqNode = (BigInt(a4[2]) << 32n) | BigInt(a4[3])
}
// simulate the 48-bit node-id and 13-bit clock-seq
// to combine with 3-bit uuid-variant
return this.xnode48_ = clockSeqNode & 0xFFFF_FFFF_FFFFn;
}
static get jdNow()/*:<double#ns7>*/{
// return 2440587.5+Date.now()/864e5 // <- Date-quantum-ms form (7ns form below)
return this.jdFromNs7(this.ns7Now)
}
static get ns7Now()/*:<BigInt#60>*/{
if(typeof performance !== 'undefined' && performance.now)
Reflect.defineProperty(this, 'ns7Now',
Reflect.getOwnPropertyDescriptor(this,'ns7Now_performance'))
else
Reflect.defineProperty(this, 'ns7Now',
Reflect.getOwnPropertyDescriptor(this, 'ns7Now_Date'))
return this.ns7Now
}
static get ns7Now_Date()/*:<BigInt#60>*/{
// const epoch1582Ns7_bias = 0x1b2_1dd2_1381_4000 // V1 1582 Oct 15
// const epoch1601Ns7_bias = 0x19d_b1de_d53e_8000n // FILETIME base
const epoch1970Ns7 = BigInt(Date.now() * 1000_0.0)
return epoch1970Ns7 + 0x1b2_1dd2_1381_4000n
}
static get ns7Now_performance()/*:<BigInt#60>*/{
const epochPgNs7 = BigInt(performance.now()*/*15*/1000_0.0|/*17*/0)
if(!this.epoch1970PgNs7) // performance.timing.navigationStart
this.epoch1970PgNs7 = this.ns7Now_Date - epochPgNs7
return epochPgNs7 + this.epoch1970PgNs7
}
static dateFromJd(jd) {return new Date((jd - 2440587.5) * 864e5)}
static dateFromNs7(ns7) {
return new Date(Number(ns7 - 0x1b2_1dd2_1381_4000n) / 1000_0.0)}
static jdFromNs7(ns7) { // atomic-clock leap-seconds (ignored)
return 2440587.5 + (Number(ns7 - 0x1b2_1dd2_1381_4000n) / 864e9)
}
static ns7FromJd(jd) {
return BigInt((jd - 2440587.5) * 864e9) + 0x1b2_1dd2_1381_4000n
}
static getRandomValues(va/*:<Uint32Array>*/) {
if(typeof crypto !== 'undefined' && crypto.getRandomValues)
crypto.getRandomValues(va)
else for(let i = 0, n = va.length; i < n; i += 1)
va[i] = Math.random() * 0x1_0000_0000 >>> 0
}
static get a4() {return this.a4_ || (this.a4_ = new Uint32Array(4))}
static ntohl(v)/*:<BigInt>*/{
let r = '0x', sign = 1n, s = BigInt(v).toString(16)
if(s[0] == '-') s = s.substr(1), sign = -1n
for(let i = s.length; i > 0; i -= 2)
r += (i == 1) ? ('0' + s[i-1]) : s[i-2] + s[i-1]
return sign*BigInt(r)
}
static ntohl32(v)/*:<Number>*/{return Number(this.ntohl(v))}
}
总结
雖然有,但我希望這對現在有足夠的解釋;試試。
在GitHub上发布 EdgeS Web-Client Eswc 图书馆的一部分时, indexedDb 使用模式与 efs 将作为其设计意图的示例,其中包括处理效率和可用性与 indexedDb 和相关 PWA 同步和复制场景。
Related朱利安日计算在JavaScript中
基准评分 Novids/sec
const start = Xuid.ns7Now
for(let i = 100000; i; i -=1)
Xuid.v4New
const end = Xuid.ns7Now
console.log(`Delta 7ns: ${(end-start)/100000n}`)
这可能对某人有用......
var d = new Date().valueOf();
var n = d.toString();
var result = '';
var length = 32;
var p = 0;
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
for (var i = length; i > 0; --i){
result += ((i & 1) && n.charAt(p) ? '<b>' + n.charAt(p) + '</b>' : chars[Math.floor(Math.random() * chars.length)]);
if(i & 1) p++;
};
HTTPS://jsfiddle.net/j0evrdf1/1/