Saturday, March 8, 2008

GUIDs, UUIDs, and Canonical Names in JavaScript

Creating unique identifiers outside of a database tends to be a bit of a pain. So, why would you do it? What if you were not using a database? What if you have distributed servers? What if you want clients to be able create distinguishable content without constantly contacting the server? For example, if clients are aggressively creating parallel content, then it would be advantageous for you to be able to lazily sync the content without causing significant lag and interruption to the user. I realize that most of you will not run into this, but for those of you who do, here are some helpful notes:

Firstly, I can't tell you how many postings I found that led to tutorials using an ActiveX object to create a UUID. If you have only IE-using clients that do not have stringent security settings, then I guess you can use this. Otherwise, it is no good.

I soon found This UUID library from AF-Design, which is alright, but there are obvious inefficiencies, such as the way it computes time in milliseconds out the long way instead of just using Date.getTime(). Also, a serious design flaw is that it doesn't use any unique data other than time in milliseconds to generate the UUID. To be a true UUID, it would need to utilize unique data to the machine such as IP, or even better the MAC address. Otherwise two machines could potentially generate the same UUID.

Understandably, there is no method for fetching the mac or ip address using only JavaScript within a browser. But, you can make the client's IP available to the JavaScript running on the client browser by echo-ing back the REMOTE_ADDR from a request header back to the client. For an example of how to do this in PHP, see http://unix.cms.gre.ac.uk/code/php/examples/remote_addr.php.

Since I usually do not care to have my unique id's in the traditional UUID format, I tend to go with a canonical name using an MD5 hash of the time and IP. The result is more reliable than the UUID example above, and is actually a bit faster and easy to implement:


function cn() {
var t = (new Date()).getTime();
var ip = '192.168.1.100';
return MD5(t+ip);
}


I hope this helps any of you dealing with a similar design problem.

No comments: