我正在尝试在JavaScript中创建全局唯一的标识符。我不确定哪些例程在所有浏览器上都可用,以及内置随机数生成器的“随机性”和种子化程度,等等。
GUID / UUID应至少为32个字符,并且应保持在ASCII范围内,以避免在传递它们时遇到麻烦。
发布于 2012-01-11 03:38:54
我真的很喜欢Broofa's answer的干净,但不幸的是poor implementations of Math.random
留下了冲突的机会。
这里有一个类似的RFC4122版本4兼容的解决方案,它通过将前13个十六进制数字偏移时间戳的十六进制部分,并在页面加载后将耗尽的偏移量偏移微秒的十六进制部分来解决该问题。这样,即使Math.random
位于同一种子上,两个客户端也必须生成自页面加载以来完全相同的微秒数(如果支持高性能时间),并且在完全相同的毫秒(或10,000+年后)生成相同的UUID:
function generateUUID() { // Public Domain/MIT
var d = new Date().getTime();//Timestamp
var d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now()*1000)) || 0;//Time in microseconds since page-load or 0 if unsupported
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16;//random number between 0 and 16
if(d > 0){//Use timestamp until depleted
r = (d + r)%16 | 0;
d = Math.floor(d/16);
} else {//Use microseconds since page-load if supported
r = (d2 + r)%16 | 0;
d2 = Math.floor(d2/16);
}
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
var onClick = function(){
document.getElementById('uuid').textContent = generateUUID();
}
onClick();
#uuid { font-family: monospace; font-size: 1.5em; }
<p id="uuid"></p>
<button id="generateUUID" onclick="onClick();">Generate UUID</button>
用于ES6的现代化代码段
const generateUUID = () => {
let
d = new Date().getTime(),
d2 = (performance && performance.now && (performance.now() * 1000)) || 0;
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
let r = Math.random() * 16;
if (d > 0) {
r = (d + r) % 16 | 0;
d = Math.floor(d / 16);
} else {
r = (d2 + r) % 16 | 0;
d2 = Math.floor(d2 / 16);
}
return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
};
const onClick = (e) => document.getElementById('uuid').textContent = generateUUID();
document.getElementById('generateUUID').addEventListener('click', onClick);
onClick();
#uuid { font-family: monospace; font-size: 1.5em; }
<p id="uuid"></p>
<button id="generateUUID">Generate UUID</button>
发布于 2017-05-20 04:50:22
使用:
let uniqueId = Date.now().toString(36) + Math.random().toString(36).substring(2);
document.getElementById("unique").innerHTML =
Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
<div id="unique">
</div>
如果ID的生成间隔超过1毫秒,则它们是100%唯一的。
如果以较短的间隔生成两个If,并假设随机方法是真正随机的,这将生成99.99999999999999%的全局唯一的If(10^15中的1个发生冲突)。
您可以通过添加更多数字来增加此数字,但要生成100%唯一的ID,您将需要使用全局计数器。
如果需要RFC兼容性,此格式将作为有效的版本4 GUID传递:
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>
上面的代码遵循RFC的意图,但不遵循RFC的字母。在其他差异中,它少了几个随机数字。(如果你需要,可以添加更多的随机数字)好处是这真的很快:)你可以test validity of your GUID here
发布于 2009-05-17 03:39:24
这里有一些基于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;
}
https://stackoverflow.com/questions/105034
复制相似问题