Skip to content

Commit

Permalink
Generating true random v4 UUIDs.
Browse files Browse the repository at this point in the history
This also makes the String::uuid() 3 times faster
  • Loading branch information
lorenzo committed Aug 24, 2014
1 parent 0667917 commit b08e0c2
Showing 1 changed file with 14 additions and 59 deletions.
73 changes: 14 additions & 59 deletions src/Utility/String.php
Expand Up @@ -27,71 +27,26 @@ class String {
*
* @see http://www.ietf.org/rfc/rfc4122.txt
* @return string RFC 4122 UUID
* @copyright Matt Farina MIT License https://github.com/lootils/uuid/blob/master/LICENSE
*/
public static function uuid() {
$node = env('SERVER_ADDR');
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
mt_rand(0, 65535), mt_rand(0, 65535),

if (strpos($node, ':') !== false) {
if (substr_count($node, '::')) {
$node = str_replace(
'::', str_repeat(':0000', 8 - substr_count($node, ':')) . ':', $node
);
}
$node = explode(':', $node);
$ipSix = '';

foreach ($node as $id) {
$ipSix .= str_pad(base_convert($id, 16, 2), 16, 0, STR_PAD_LEFT);
}
$node = base_convert($ipSix, 2, 10);
// 16 bits for "time_mid"
mt_rand(0, 65535),

if (strlen($node) < 38) {
$node = null;
} else {
$node = crc32($node);
}
} elseif (empty($node)) {
$host = env('HOSTNAME');
// 12 bits before the 0100 of (version) 4 for "time_hi_and_version"
mt_rand(0, 4095) | 0x4000,

if (empty($host)) {
$host = env('HOST');
}

if (!empty($host)) {
$ip = gethostbyname($host);

if ($ip === $host) {
$node = crc32($host);
} else {
$node = ip2long($ip);
}
}
} elseif ($node !== '127.0.0.1') {
$node = ip2long($node);
} else {
$node = null;
}

if (empty($node)) {
$node = crc32(Configure::read('Security.salt'));
}

if (function_exists('hphp_get_thread_id')) {
$pid = hphp_get_thread_id();
} elseif (function_exists('zend_thread_id')) {
$pid = zend_thread_id();
} else {
$pid = getmypid();
}

if (!$pid || $pid > 65535) {
$pid = mt_rand(0, 0xfff) | 0x4000;
}
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
mt_rand(0, 0x3fff) | 0x8000,

list($timeMid, $timeLow) = explode(' ', microtime());
return sprintf(
"%08x-%04x-%04x-%02x%02x-%04x%08x", (int)$timeLow, (int)substr($timeMid, 2) & 0xffff,
mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3f) | 0x80, mt_rand(0, 0xff), $pid, $node
// 48 bits for "node"
mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)
);
}

Expand Down

0 comments on commit b08e0c2

Please sign in to comment.