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.
Fastest GUID like string generator method in the format
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
. This does not generate standard-compliant GUID.Ten million executions of this implementation take just 32.5 seconds, which is the fastest I've ever seen in a browser (the only solution without loops/iterations).
The function is as simple as:
To test the performance, you can run this code:
I'm sure most of you will understand what I did there, but maybe there is at least one person that will need an explanation:
The algorithm:
Math.random()
function returns a decimal number between 0 and 1 with 16 digits after the decimal fraction point (for example0.4363923368509859
).0.6fb7687f
).Math.random().toString(16)
.0.
prefix (0.6fb7687f
=>6fb7687f
) and get a string with eight hexadecimal characters long.(Math.random().toString(16).substr(2,8)
.Math.random()
function will return shorter number (for example0.4363
), due to zeros at the end (from the example above, actually the number is0.4363000000000000
). That's why I'm appending to this string"000000000"
(a string with nine zeros) and then cutting it off withsubstr()
function to make it nine characters exactly (filling zeros to the right).Math.random()
function will return exactly 0 or 1 (probability of 1/10^16 for each one of them). That's why we needed to add nine zeros to it ("0"+"000000000"
or"1"+"000000000"
), and then cutting it off from the second index (3rd character) with a length of eight characters. For the rest of the cases, the addition of zeros will not harm the result because it is cutting it off anyway.Math.random().toString(16)+"000000000").substr(2,8)
.The assembly:
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
.XXXXXXXX
and-XXXX-XXXX
.XXXXXXXX
-XXXX-XXXX
-XXXX-XXXX
XXXXXXXX
._p8(s)
, thes
parameter tells the function whether to add dashes or not._p8() + _p8(true) + _p8(true) + _p8()
, and return it.Link to this post on my blog
Enjoy! :-)
From sagi shkedy's technical blog:
There are other methods that involve using an ActiveX control, but stay away from these!
Edit : I thought it was worth pointing out that no GUID generator can guarantee unique keys (check the wikipedia article). There is always a chance of collisions. A GUID simply offers a large enough universe of keys to reduce the change of collisions to almost nil.
This one is based on date, and add a random suffix to "ensure" uniqueness. Works well for css identifiers. It always returns something like and is easy to hack:
uid-139410573297741
For an RFC4122 version 4 compliant solution, this one-liner(ish) solution is the most compact I could come up with.:
Update, 2015-06-02: Be aware that UUID uniqueness relies heavily on the underlying random number generator (RNG). The solution above uses
Math.random()
for brevity, howeverMath.random()
is not guaranteed to be a high-quality RNG. See Adam Hyland's excellent writeup on Math.random() for details. For a more robust solution, consider something like the uuid module[Disclaimer: I'm the author], which uses higher quality RNG APIs where available.Update, 2015-08-26: As a side-note, this gist describes how to determine how many IDs can be generated before reaching a certain probability of collision. For example, with 3.26x1015 version 4 RFC4122 UUIDs you have a 1-in-a-million chance of collision.
Update, 2017-06-28: A good article from Chrome developers discussing the state of Math.random PRNG quality in Chrome, Firefox, and Safari. tl;dr - As of late-2015 it's "pretty good", but not cryptographic quality. To address that issue, here's an updated version of the above solution that uses ES6, the
crypto
API, and a bit of JS wizardy I can't take credit for:JavaScript project on GitHub - https://github.com/LiosK/UUID.js
Adjusted my own UUID/GUID generator with some extras here.
I'm using the following Kybos random number generator to be a bit more cryptographically sound.
Below is my script with the Mash and Kybos methods from baagoe.com excluded.