So I\'ve been doing some digging around and I\'ve been trying to piece together a function that generates a valid v4 UUID in PHP. This is the closest I\'ve been able to come
I'm sure there's a more elegant way to do the conversion from binary to decimal for the 4xxx
and yxxx
portions. But if you want to use openssl_random_pseudo_bytes
as your crytographically secure number generator, this is what I use:
return sprintf('%s-%s-%04x-%04x-%s',
bin2hex(openssl_random_pseudo_bytes(4)),
bin2hex(openssl_random_pseudo_bytes(2)),
hexdec(bin2hex(openssl_random_pseudo_bytes(2))) & 0x0fff | 0x4000,
hexdec(bin2hex(openssl_random_pseudo_bytes(2))) & 0x3fff | 0x8000,
bin2hex(openssl_random_pseudo_bytes(6))
);
A slight variation on Jack's answer to add support for PHP < 7:
// Get an RFC-4122 compliant globaly unique identifier
function get_guid() {
$data = PHP_MAJOR_VERSION < 7 ? openssl_random_pseudo_bytes(16) : random_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // Set version to 0100
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // Set bits 6-7 to 10
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
$uuid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex(random_bytes(16)), 4));
Inspired by broofa's answer here.
preg_replace_callback('/[xy]/', function ($matches)
{
return dechex('x' == $matches[0] ? mt_rand(0, 15) : (mt_rand(0, 15) & 0x3 | 0x8));
}
, 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx');
Or if unable to use anonymous functions.
preg_replace_callback('/[xy]/', create_function(
'$matches',
'return dechex("x" == $matches[0] ? mt_rand(0, 15) : (mt_rand(0, 15) & 0x3 | 0x8));'
)
, 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx');
Taken from this comment on the PHP manual, you could use this:
function gen_uuid() {
return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
// 16 bits for "time_mid"
mt_rand( 0, 0xffff ),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
mt_rand( 0, 0x0fff ) | 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,
// 48 bits for "node"
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
);
}
How about using mysql to generate the uuid for you?
$conn = new mysqli($servername, $username, $password, $dbname, $port);
$query = 'SELECT UUID()';
echo $conn->query($query)->fetch_row()[0];