如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。
我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。
当前回答
因此,注意到这篇文章有超过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}`)
其他回答
ES6 样品
const guid=()=> {
const s4=()=> Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
return `${s4() + s4()}-${s4()}-${s4()}-${s4()}-${s4() + s4() + s4()}`;
}
根據 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)
因此,开发人员为生产环境编写代码被鼓励使用严格,良好的实施,如新模块。
它提供简单,快速的生成RFC4122 UUIDS。
特性:
创建 RFC4122 版本 1 或版本 4 UUIDs 在 Node.js 和浏览器中运行. 在支持平台上加密强大的随机 # 发行。
使用 NPM 安装:
npm install uuid
或者通过浏览器使用 uuid:
下载原始文件(uuid v1): https://raw.githubusercontent.com/kelektiv/node-uuid/master/v1.js 下载原始文件(uuid v4): https://raw.githubusercontent.com/kelektiv/node-uuid/master/v4.js
想要更小? 查看此: https://gist.github.com/jed/982883
使用:
// Generate a v1 UUID (time-based)
const uuidV1 = require('uuid/v1');
uuidV1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'
// Generate a v4 UUID (random)
const uuidV4 = require('uuid/v4');
uuidV4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
// Generate a v5 UUID (namespace)
const uuidV5 = require('uuid/v5');
// ... using predefined DNS namespace (for domain names)
uuidV5('hello.example.com', v5.DNS)); // -> 'fdda765f-fc57-5604-a269-52a7df8164ec'
// ... using predefined URL namespace (for, well, URLs)
uuidV5('http://example.com/hello', v5.URL); // -> '3bbcee75-cecc-5b56-8031-b6641c1ed1f1'
// ... using a custom namespace
const MY_NAMESPACE = '(previously generated unique uuid string)';
uuidV5('hello', MY_NAMESPACE); // -> '90123e1c-7512-523e-bb28-76fab9f2f73d'
ECMAScript 2015(ES6):
import uuid from 'uuid/v4';
const id = uuid();
[编辑 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() 的解决方案不提供良好的独特性保证。
简单的JavaScript作为这个问题的最佳答案的组合。
var crypto = window.crypto || window.msCrypto || null; // IE11 fix var Guid = Guid || (function() { var EMPTY = '00000000-0000-0000-0000-000000000000'; var _padLeft = function(paddingString, width, replacementChar) { return paddingString.length >= width ? paddingString : _padLeft(replacementChar + paddingString, width, replacementChar || ' '); }; var _s4 = function(number) { var hexadecimalResult = number.toString(16); return _padLeft(hexadecimalResult, 4, '0'); }; var _cryptoGuid = function() { var buffer = new window.Uint16Array(8); crypto.getRandomValues(buffer); return [_s4(buffer[0]) + _s4(buffer[1]), _s4(buffer[2]), _s4(buffer[3]), _s4(buffer[4]), _s4(buffer[5]) + _s4(buffer[6]) + _s4(buffer[7])].join('-'); }; var _guid = function() { var currentDateMilliseconds = new Date().getTime(); return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(currentChar) { var randomChar = (currentDateMilliseconds + Math.random() * 16) % 16 | 0; currentDateMilliseconds = Math.floor(currentDateMilliseconds / 16); return (currentChar === 'x' ? randomChar : (randomChar & 0x7 | 0x8)).toString(16); }); }; var create = function() { var hasCrypto = crypto != 'undefined' && crypto !== null, hasRandomValues = typeof(window.crypto.getRandomValues) != 'undefined'; return (hasCrypto && hasRandomValues) ? _cryptoGuid() : _guid(); }; return { newGuid: create, empty: EMPTY }; })(); // DEMO: Create and show GUID console.log('1. New Guid: ' + Guid.newGuid()); // DEMO: Show empty GUID console.log('2. Empty Guid: ' + Guid.empty);
使用:
主持人( )
“c6c2d12f-d76b-5739-e551-07e6de5b0807”
公平 公平
“00000000-0000-0000-0000-00000000”