note 72538 added to function.uniqid
| From: | lance_rushing at hotmail dot com | 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