如何将php的uuid v4转换为两个64位整数

时间:2016-10-05 07:22:40

标签: php uuid

实施例: 从v4的v4生成的Uuid: 8bc278cb-2fb6-413b-add6-8ba39bf830e8

我想将其转换为两个64位整数。

我尝试使用php的hexdec,但它的返回值是数字。我想要数据类型整数。

有趣的是:

我已尝试将hexdec与上面的uuid一起使用并将此输出用于dechex。一些如何,没有得到相同的价值?

对此有任何见解将不胜感激。

2 个答案:

答案 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. Stack Overflow:16 bytes binary form of canonical uuid representation in php
  2. Stack Overflow:How to convert byte array to integer in php?
  3. PHP手册:pack()

答案 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));