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
Instead of breaking it down into individual fields, it's easier to generate a random block of data and change the individual byte positions. You should also use a better random number generator than mt_rand().
According to RFC 4122 - Section 4.4, you need to change these fields:
time_hi_and_version
(bits 4-7 of 7th octet),clock_seq_hi_and_reserved
(bit 6 & 7 of 9th octet)All of the other 122 bits should be sufficiently random.
The following approach generates 128 bits of random data using openssl_random_pseudo_bytes(), makes the permutations on the octets and then uses bin2hex() and vsprintf() to do the final formatting.
function guidv4($data)
{
assert(strlen($data) == 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));
}
echo guidv4(openssl_random_pseudo_bytes(16));
With PHP 7, generating random byte sequences is even simpler using random_bytes():
function guidv4($data = null)
{
$data = $data ?? random_bytes(16);
// ...
}