Как преобразовать uuid v4 из php в два 64-битных целых числа

Пример: Uuid, сгенерированный из v4 php: 8bc278cb-2fb6-413b-add6-8ba39bf830e8

Я хочу преобразовать это в два 64-битных целых числа.

Я пытался использовать hexdec PHP, но это возвращаемое значение из чисел. Я хочу, чтобы тип данных integer.

Что интересно:

Я попытался использовать hexdec с вышеупомянутым uuid и использовал этот вывод для dechex. Кое-как, не получая того же значения?

Любое понимание этого будет оценено.

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. Переполнение стека: 16-байтовая двоичная форма канонического представления uuid в php
  2. Переполнение стека: Как преобразовать массив байтов в целое число в php?
  3. Руководство по PHP: pack ()

В то время как в других языках ( например, в 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, UUID как два 64-битных целых числа должен поддерживать значения до 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));
Другие вопросы по тегам