Javascript UUID Function
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 – an alternate implementation for RFC4122v4 UUIDs designed to be as compact as possible.
Unfortunately, I can’t integrate OSL code in an MIT licensed distribution because of its viral clause. Sorry. I’m building a collection of portable JavaScript “modules” and promoting a standard for module loaders. Please let me know if you read the license differently.
This is very interesting. Can I ask what you use it for?
@kris: Can you be more specific about the license incompatabilities? Any suggestions as to which license would be most appropriate for something like this?
@stephen: Sure. If you have a web app with a data model on the client, this allows the client to assign permanent IDs to objects when they are created, rather than having to issue a server request to get an ID (like you would normally have to do in a more traditional architecture.)
I think this has a bug that causes it to fail in IE7. IE7 does not allow you to extract characters from a string using square brackets, you have to use the .charAt() function.
Alternatively, you could change this line:
var c = ‘0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz’;
to this:
var c = ‘0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz’.split(”);
then c is an array and should work in all browsers.
Good Catch, Brian. I’ve updated the script to use the split() fix as you suggested. (If the code looks a little odd to anyone, it’s because I cache the split() version of the string on the function object. But in order to do that without requiring a cumbersome declaration outside of the function, I use arguments.callee to get the function object from within itself. It’s a little kludgy, but it keeps the method nice and self-contained.)
save to my Bookmarks
What’s the license of this script? GPL, MIT?
BSD – It’s in the script source.Update: Now dual MIT/GPL licensed.
When I run the Math.uuid.js test page in IE6 on WinXP I get a javascript error at the line below. Crome and FF work fine of course. Anybody else report/fix this problem.
var args = ARGS.shift(), length = args[0] || 0, radix = args[1] || 62;
Here is the specifi error:
—————————
Error
—————————
A Runtime Error has occurred.
Do you wish to Debug?
Line: 33
Error: ‘0′ is null or not an object
—————————
Yes No
—————————
This page is an awsome reference. I’d add this to the Wikkipedia UUID page if I know that this problem with IE is an isolated problem.
@Troy – Good catch. The problem was in the test page code, not the Math.uuid() function. ‘Just a trailing comma error, *dooh*. I’ve fixed it and it should be working now. Thanks for the report!
Wow! that was fast. Thanks for fixing this so quickly.
There is one typo that I found. The linked text for RFC4122 above is RFC4142
@Troy: Fixed. Thanks.
Is there a shorter version of the license text I could use along with a URL to the full license? I’d like to include a modified version of this script in some work and the license text is pretty bulky.
Sorry, leaving another comment so I get email updates.
Great, just what I was looking for for use in an Adobe AIR app that has client/server sync. Thanks much!
Licensing: I’m not sure what Kris means about the ‘viral clause’, but I also cannot include code in my open source releases unless it uses MPL or the MIT License. The MIT License is particularly simple and easy to use: http://www.opensource.org/licenses/mit-license.php
It would be great if you switched to the MIT License!
The revised BSD license is fully GPL compatible and OSI approved. It is essentially equivalent to the MIT License, and doesn’t have a viral clause. Hope that clears things up for anybody stumbling across this!
This code is now dual licensed under MIT and GPL. I’ve also shortened the verbiage to this effect in the source so it’s not so unwieldy.
Thanks! A real little gem
Great script!