Javascript UUID Function

[UPDATE – 1/3/2010: For the latest/greatest implementation of a JavaScript UUID function, please check out my node-uuid project.  Any future improvements/enhancements to this code will be made there.]

[UPDATE – 9/1/2011: ‘Seeing reports of UUID collisions in the wild.  Johannes Baagoe has a write up on why Math.random() can’t be trusted.  I’m not entirely sure I buy this, but I’m certainly less confident than before about the uniqueness of UUIDs generated using only Math.random().]

Here’s a little JavaScript treat: Math.uuid.js is a function for generating different flavors of UUIDs in JavaScript. The function supports RFC 4122-compliant UUIDs (or GUIDS), like this:

AFF147E4-5BB1-448E-B55D-0A834ADE3124

… as well as non-standard random IDs of arbitrary length and radix. For examples of the types of IDs it can generate, or to see performance data, check out the Math.uuid.js Test page.

I put this together after discovering that nobody had published a really thin javascript implementation for generating UUIDs. Googling around turns up several decent scripts, but all of these suffered from one drawback or another (IMHO). One common problem results from trying to produce “version 1″ ids, which the RFC defines in a way that is supposed to guarantee the uniqueness of the ID. But javascript doesn’t have an API for getting a guaranteed-unique anything – the best you can do is use Math.random() as a hack workaround which, strictly speaking, shouldn’t be used when uniqueness must be guaranteed. Using JavaScript to generate a version 1 UUID could be construed as misleading.

The more correct solution is to do what Math.uuid.js does – create “version 4″ ids, which are defined as randomly generated (see RFC 4122, section 4.4). This avoids making an unfulfilled promise of universal uniqueness, while allowing for much simpler code. Also, in javascript where Math.random() has to be used for UUID generation, the theoretical uniqueness of these ids is better than version 1 implementations since all 122 bits of field data are randomly generated. That makes for a staggering 5.3 x 10^^36 possible ids. If every person on the planet filled up a terabyte hard drive with nothing but random UUIDs, there would only be a one in 7 trillion chance that two of the UUIDs would be the same. That’s the theory.

The practice is probably a little different. The uniqueness depends on how random the numbers generated by Math.random() are. Generating truly random numbers is a notoriously tricky problem, solved in different (imperfect) ways across browser platforms and OSes. It’s difficult to say for sure what the real-world uniqueness of these numbers ends up being, but I suspect it’s more than sufficient for most purposes. Regardless, this is a weakness that all javascript UUID generators will be subject to, unless they rely on an externally-provided unique value. For example, one could use AJAX to fetch UUIDs generated by a site like http://www.uuidgenerator.com/, but that has it’s own set of issues.

Update 1/22/10: Math.uuid.js includes an Math.uuid2 Math.uuidCompact – an alternate implementation for RFC4122v4 UUIDs designed to be as compact as possible, and Math.uuidFast() – an implementation designed for performance.

Update 06/03/10: Several people have expressed concern over how random the Math.random() method is. (E.g. “If two clients load the random() lib at the same time, will they start with the same seed?”) After doing a bit of research into how various OSes handle random # generation , I’m pretty satisfied that this unlikely to be an issue.  Seeding is done from a variety of sources of almost pure random numbers – mouse movement, built-in hardware support (e.g. by measuring noise in electrical circuits), various unique device IDs, BIOS checksums, memory usage statistics… and so on.