note 72538 added to function.uniqid

From: Date: Tue, 23 Jan 2007 20:43:49 +0000
Subject: note 72538 added to function.uniqid
Groups: php.notes 
Request: Send a blank email to php-notes+get-122082@lists.php.net to get a copy of this message
wooshoofoo, the reason mimec is calling mt_rand multiple times is because the largest number mt_rand can produce is 2^31 (2147483647, as reported by mt_getrandmax() on my server). RFC 4122 requires a 128 bit value. Also they are not "4 digit sequeces", but 4 digit hexadecimal numbers. 16^4 == 2^16. mimec's limiting each random result to 2^16 avoids problem of PHP's 2^32 integer max (http://php.net/manual/en/language.types.integer.php). If you want to call mt_rand fewer times: mimec's version calls mt_rand 8 times ( 16 bits * 8 = 128 bits ). You *could* call mt_rand 5 times ( 31 bits + 31 bits + 31 bits + 31 bits + 4 bits = 128 bits ). But then you would have keep all your values as strings. Something like: <?php /** * Another (ugly) "random or pseudo-random" version of RFC 4122 * * This version calls mt_rand() the fewest possible times. * if mt_getrandmax() == 2^31 then this will call mt_rand() 5 times YMMV * * Personally, I would use mimec's version * To handle the large values, we'll keep everything as strings. * * @return string */ function uuid() { // Generate 128 bit random sequence $randmax_bits = strlen(base_convert(mt_getrandmax(), 10, 2)); // how many bits is mt_getrandmax() $x = ''; while (strlen($x) < 128) { $maxbits = (128 - strlen($x) < $randmax_bits) ? 128 - strlen($x) : $randmax_bits; $x .= str_pad(base_convert(mt_rand(0, pow(2,$maxbits)), 10, 2), $maxbits, "0", STR_PAD_LEFT); } // break into fields $a = array(); $a['time_low_part'] = substr($x, 0, 32); $a['time_mid'] = substr($x, 32, 16); $a['time_hi_and_version'] = substr($x, 48, 16); $a['clock_seq'] = substr($x, 64, 16); $a['node_part'] = substr($x, 80, 48); // Apply bit masks for "random or pseudo-random" version per RFC $a['time_hi_and_version'] = substr_replace($a['time_hi_and_version'], '0100', 0, 4); $a['clock_seq'] = substr_replace($a['clock_seq'], '10', 0, 2); // Format output return sprintf('%s-%s-%s-%s-%s', str_pad(base_convert($a['time_low_part'], 2, 16), 8, "0", STR_PAD_LEFT), str_pad(base_convert($a['time_mid'], 2, 16), 4, "0", STR_PAD_LEFT), str_pad(base_convert($a['time_hi_and_version'], 2, 16), 4, "0", STR_PAD_LEFT), str_pad(base_convert($a['clock_seq'], 2, 16), 4, "0", STR_PAD_LEFT), str_pad(base_convert($a['node_part'], 2, 16), 12, "0", STR_PAD_LEFT)); } ?> However, I think mimec's version is much more elegant. ---- Server IP: 216.194.113.175 Probable Submitter: 209.242.156.231 ---- Manual Page -- http://www.php.net/manual/en/function.uniqid.php Edit -- https://master.php.net/note/edit/72538 Del: integrated -- https://master.php.net/note/delete/72538/integrated Del: useless -- https://master.php.net/note/delete/72538/useless Del: bad code -- https://master.php.net/note/delete/72538/bad+code Del: spam -- https://master.php.net/note/delete/72538/spam Del: non-english -- https://master.php.net/note/delete/72538/non-english Del: in docs -- https://master.php.net/note/delete/72538/in+docs Del: other reasons-- https://master.php.net/note/delete/72538 Reject -- https://master.php.net/note/reject/72538 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#122082) next »