Как преобразовать 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-битных чисел, представляющих гекс.
Ссылка
- Переполнение стека: 16-байтовая двоичная форма канонического представления uuid в php
- Переполнение стека: Как преобразовать массив байтов в целое число в php?
- Руководство по 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));