|
UUID (Universally Unique Identifier) is standard (part of ISO/IEC 11578:1996) to create “universally unique” identifiers to identify objects within a system or across system boundaries. The identifiers are 128-bit in length (that’s 16 bytes) and while there really is no way to guarantee global uniqueness the probability of colissions are very small both thanks to the number of bits and the way the identifiers are created. The UUID generation algorithms are specified in RFC4122 and I’ve created a static PHP class that implements version 1 which is time based UUID, version 4 which is truly psuedo random UUID and version 3 and 5 which are named based UUID, using either MD5 (version 3) or SHA-1 (version 5).
The class has the following public functions, their return value depends on the format argument. $mixed generate($type, $fmt = self::FMT_BYTE, $node = "", $ns = "") $mixed convert($uuid, $from, $to) UUID version constants where each constant represents a specific UUID version UUID_TIME, UUID_NAME_MD5, UUID_RANDOM, UUID_NAME_SHA1 UUID format constants
The convert method can be used to convert between these representations. UUID version 1 examplexxxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx require_once('class.uuid.php'); $str = UUID::generate(UUID::UUID_TIME, UUID::FMT_STRING, "abcdef"); print "$str\n"; Example output, the last part is the node id and will remain constant (as long as the node id is the same), the first part will change according to time while the middle part is pseudo random. 1b55e723-578b-4e34-d5cf-616263646566 The class does not fully implement version 1 as described in the RFC. The clock sequence is generated from a psuedo random generator each time a new UUID is generated and not written and read from a stable storage as described in the RFC. UUID version 4 examplexxxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx require_once('class.uuid.php'); $str = UUID::generate(UUID::UUID_RANDOM, UUID::FMT_STRING); print "$str\n"; Kind of useless example output d8988842-43d5-42b3-9049-af4bbc694dbe UUID version 3/5 examplexxxxxxxxx-xxxx-3/5xxx-xxxx-xxxxxxxxxxxx require_once('class.uuid.php'); /* * 6ba7b810-9dad-11d1-80b4-00c04fd430c8 is the DNS name space */ $md5 = UUID::generate(UUID::UUID_NAME_MD5, UUID::FMT_STRING, "www.widgets.com", '6ba7b810-9dad-11d1-80b4-00c04fd430c8'); $sha1 = UUID::generate(UUID::UUID_NAME_SHA1, UUID::FMT_STRING, "www.widgets.com", '6ba7b810-9dad-11d1-80b4-00c04fd430c8'); print "MD5: $md5\n"; print "SHA1: $sha1\n"; Example output MD5: e902893a-9d22-3c7e-a7b8-d6e313b71d9f SHA1: 13726f09-44a9-5eeb-8910-3525a23fb23b Final notesThis class have been tested with PHP 5.2.x on both little and big endian machines. While there could be bugs in the algorithm implementation at least they are consistent across platforms Get from githubLinks
15 Responses to “UUID generator for PHP”
Leave a Reply
|
Entries (RSS)
Finally! A decent implementation. It’s very hard to find one of these that wasn’t written by a muppet! I’m using this as a library class for our internal ORM framework – looks to be working very well so far. Thanks!
Just what I was looking for. Thanks!
Thank you.
I was very excited to see your implementation of RFC4122, because I was looking to use UUIDs for Atom and didn’t want something merely “UUID-like” as all these other PHP implementations are. However, I hate to break it to you, but your implementation of Version 1 UUIDs seems to be broken in a number of ways. Besides the clock sequence (which is understandable) your implementation seems to use a null MAC node (whereas it should generate a random one), but worst of all the encoding of the time is completely wrong!
If you plug the output of your generator into the time extractor at http://www.famkruithof.net/uuid/uuidgen?typeReq=-1 (which I know to be correct: I checked with known timestamp values) you’re left with a time several centuries from now. If you use a date in the past the disparity is even greater (several -millennia- from now…). I just thought you should know.
If you’re curious I also wrote my own implementation from scratch yesterday since I had no one to depend on but myself (and I didn’t like your API anyway—sorry). I’d very much like to know what you think of it.
http://jkingweb.ca/code/php/lib.uuid/
[...] besonders anspruchsvolle Situationen und Sicherheitsfanatiker hat ‘fli’ einen UUID-Generator geschrieben, der keine Wünsche offen [...]
I’ve tried on Php 5.2.6 on Windows and fall into trouble with random generation. Time_low part is generated using mt_rand with interval set to 0,0xffffffff. The mt_rand function however uses signed integer for parameter and that’s why the resulting value is always negative. When passing to sprintf the result of time_low part is always 0.
The bugs mentioned in the posts above should have been fixed now.
Thanks for the great class!
One note is that many implementations claim that the example for version 3 as shown in RFC4122 is incorrect (OSSP uuid, python) where the value generated should actually be 3d813cbb-47fb-32ba-91df-831e1593ac29. If one needs compatibility with these (and other) libraries for version 3/5 one can remove lines 163-165 and 180-182 (byte swapping lines) and get matching results.
Actually, after several hours of testing, I have identified a significant bug in this implementation. If you generate a version 3 or 5 UUID, using a namespace UUID with the first byte > 8, your code overflows, and generates invalid UUIDs. further, this invalid UUID is the same for all namespace UUIDs >80000000-0000-0000-0000-00000000000
[...] und als Klasse bereit gestellt. Bei der Suche im Netz habe ich zwei Varianten entdeckt: DrUUID und UUID Generator. Außerdem kann man auch das PECL Package uuid nutzen, welches jedoch die libuuid (des Projekts [...]
How do I convert a binary back to string or byte or field?
Uuid::convert($id, Uuid::FMT_BINARY, Uuid::FMT_STRING)
is not yet supported. It is just now that I notice the problem.
I have modified them so that it will convert binary back to string or byte etc
static private function conv_bin2byte($src) {
// array_merge – reindex since unpack starts at index 1
return array_merge(unpack(’C16′, $src));
}
static private function conv_bin2field($src) {
$byte = self::conv_bin2byte($src);
return self::conv_byte2field($byte);
}
static private function conv_bin2string($src) {
$byte = self::conv_bin2byte($src);
return self::conv_byte2string($byte);
}
[...] [...]
zapytaj…
[...]UUID generator for PHP « shapeshifter.se[...]…
Oops, just to note, I do not get the same UUID v5 with OSSP uuid removing the http:// with either, just like
uuid -v5 6ba7b810-9dad-11d1-80b4-00c04fd430c8 http://www.widgets.com