Example: Uuid generated from v4 of php : 8bc278cb-2fb6-413b-add6-8ba39bf830e8
I want to convert this into two 64 bit integers.
I've tried using hexdec
of php but it's return value is of numbers. I want datatype integer.
Interestingly :
I have tried using hexdec with the above uuid and used this output to dechex. Some how, not getting the same value?
Any insights into this will be appreciated.
UUID is a 128bit data type. Excluding the 6 reserved bits, there are 122 data bits in it. Makes it impossible to fully convert any UUID to a 64bit integer. You'll at least need to store it as 2 64bit numbers or 4 32bit numbers.
You can unpack the UUID into binary, then unpack it as 4 32bit unsigned character:
function uuidToHex($uuid) {
return str_replace('-', '', $uuid);
}
function hexToUuid($hex) {
$regex = '/^([\da-f]{8})([\da-f]{4})([\da-f]{4})([\da-f]{4})([\da-f]{12})$/';
return preg_match($regex, $hex, $matches) ?
"{$matches[1]}-{$matches[2]}-{$matches[3]}-{$matches[4]}-{$matches[5]}" :
FALSE;
}
function hexToIntegers($hex) {
$bin = pack('h*', $hex);
return unpack('L*', $bin);
}
function integersToHex($integers) {
$args = $integers; $args[0] = 'L*'; ksort($args);
$bin = call_user_func_array('pack', $args);
$results = unpack('h*', $bin);
return $results[1];
}
$uuid = '1968ec4a-2a73-11df-9aca-00012e27a270';
var_dump($uuid);
$integers = hexToIntegers(uuidToHex('1968ec4a-2a73-11df-9aca-00012e27a270'));
var_dump($integers);
$uuid = hexToUuid(integersToHex($integers));
var_dump($uuid);
It will returns
string(36) "1968ec4a-2a73-11df-9aca-00012e27a270"
array(4) {
[1]=>
int(2764998289)
[2]=>
int(4245764002)
[3]=>
int(268479657)
[4]=>
int(120222434)
}
string(36) "1968ec4a-2a73-11df-9aca-00012e27a270"
$integers
is an array 4 32bit numbers that represents the hex.
While it's common in other languages (like Java) to get the least significant and most significant bits of a UUID as two unsigned 64-bit integers, PHP has trouble with this because all integers in PHP are signed. Even if using a 64-bit build of PHP, you will run into integer overflows when trying to get a real integer value of the least or most significant bits of a UUID.
The maximum integer value on 64-bit PHP is 9,223,372,036,854,775,807
, while an unsigned 64-bit integer has a max value of 18,446,744,073,709,551,615
. A UUID as two 64-bit integers needs to support values up to 18,446,744,073,709,551,615
.
As an earlier answer mentioned, it might be better to split up the UUID into four unsigned 32-bit integers, if you need to split it up like that. (The max value of an unsigned 32-bit integer is 4,294,967,295
, which 64-bit PHP can support.)
If you're simply interested in storing a UUID in a more optimized way, you can convert it to a 16-byte binary string:
$uuid = '1968ec4a-2a73-11df-9aca-00012e27a270';
$binaryUuid = hex2bin(str_replace('-', '', $uuid));