Create GUID / UUID in JavaScript?
I'm trying to create globally-unique identifiers in JavaScript. I'm not sure what routines are available on all browsers, how "random" and seeded the built-in random number generator is, etc..
The GUID / UUID should be at least 32 characters and should stay in the ASCII range to avoid trouble when passing them around.
There have been a couple attempts at this. The question is: do you want actual GUIDs, or just random numbers that look like GUIDs? It's easy enough to generate random numbers.
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
However, note that such values are not genuine GUIDs .
There's no way to generate real GUIDs in Javascript, because they depend on properties of the local computer that browsers do not expose. You'll need to use OS-specific services like ActiveX: http://p2p.wrox.com/topicindex/20339.htm
Edit: not correct - RFC4122 allows random ("version 4") GUIDs. See other answers for specifics.
Note : the provided code snippet does not follow RFC4122 which requires that the version ( 4
) has to be integrated into the generated output string. Do not use this answer if you need compliant GUIDs.
Use:
var uuid = guid();
Demo:
function guid() {
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
document.getElementById('jsGenId').addEventListener('click', function() {
document.getElementById('jsIdResult').value = guid();
})
input { font-family: monospace; }
<button id="jsGenId" type="button">Generate GUID</button>
<br>
<input id="jsIdResult" type="text" placeholder="Results will be placed here..." readonly size="40"/>
对于符合RFC4122版本4的解决方案,这种单线(ish)解决方案是我能想到的最紧凑的解决方案。
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
console.log(uuidv4())
I really like how clean Broofa's answer is, but it's unfortunate that poor implementations of Math.random
leave the chance for collision.
Here's a similar RFC4122 version 4 compliant solution that solves that issue by offsetting the first 13 hex numbers by a hex portion of the timestamp. That way, even if Math.random
is on the same seed, both clients would have to generate the UUID at the exact same millisecond (or 10,000+ years later) to get the same UUID:
function generateUUID() { // Public Domain/MIT
var d = new Date().getTime();
if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
d += performance.now(); //use high-precision timer if available
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
Here's a fiddle to test.
上一篇: 我如何迭代枚举?