实施例:
从v4的v4生成的Uuid:
8bc278cb-2fb6-413b-add6-8ba39bf830e8
我想将其转换为两个64位整数。
我尝试使用php的hexdec
,但它的返回值是数字。我想要数据类型整数。
有趣的是:
我已尝试将hexdec与上面的uuid一起使用并将此输出用于dechex。一些如何,没有得到相同的价值?
对此有任何见解将不胜感激。
答案 0 :(得分:2)
UUID是128位数据类型。排除6个保留位,其中有122个数据位。使任何UUID完全转换为64位整数是不可能的。您至少需要将其存储为2个64位数字或4个32位数字。
您可以将UUID解压缩为二进制文件,然后将其解压缩为4 32位无符号字符:
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);
它将返回
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
是一个数组4个32位数字,表示十六进制。
答案 1 :(得分:1)
虽然在其他语言(like Java)中常见的是将UUID的最低有效位和最高有效位作为两个无符号64位整数,但PHP遇到了麻烦,因为PHP中的所有整数都是如此签了。即使使用64位版本的PHP,在尝试获取UUID的最小或最高位的实际整数值时也会遇到整数溢出。
64位PHP上的最大整数值为9,223,372,036,854,775,807
,而无符号的64位整数的最大值为18,446,744,073,709,551,615
。作为两个64位整数的UUID需要支持最多18,446,744,073,709,551,615
的值。
正如前面提到的一个答案,如果你需要将UUID拆分成四个无符号的32位整数,可能会更好。 (无符号32位整数的最大值为4,294,967,295
,64位PHP可以支持。)
如果您只是想以更优化的方式存储UUID,可以将其转换为16字节的二进制字符串:
$uuid = '1968ec4a-2a73-11df-9aca-00012e27a270';
$binaryUuid = hex2bin(str_replace('-', '', $uuid));