Reputation: 282915
pack
doesn't support them, so how to read and write 64-bit unsigned little-endian encoded integers?
Upvotes: 3
Views: 770
Reputation: 7434
You could consider 64 bit numbers as an opaque chunk of 8 bytes of binary data and use the usual string manipulation functions to handle them (i.e. substr
and the dot operator above all).
Whenever (and if) you need to perform arithmetics on them, you can use a couple of wrapper functions to encode/decode that chunk in its hexadecimal representation (in my implementation I call this intermediate type hex64
) and use the external library you prefer to do the real work:
<?php
/* Save as test.php */
function chunk_to_hex64($chunk) {
assert(strlen($chunk) == 8);
return strrev(bin2hex($chunk));
}
function hex64_to_chunk($hex64) {
assert(strlen($hex64) == 16);
return strrev(pack('h*', $hex64));
}
// Test code:
function to_hex64($number) {
$hex64 = base_convert($number, 10, 16);
// Ensure the hex64 is left padded with '0'
return str_pad($hex64, 16, '0');
}
for ($number = 0.0; $number < 18446744073709551615.0; $number += 2932031007403.0) {
$hex64 = to_hex64($number);
$hex64_reencoded = chunk_to_hex64(hex64_to_chunk($hex64));
assert($hex64_reencoded == $hex64, "Result is $hex64_reencoded, expected $hex64");
}
$data = file_get_contents('test.php');
// Skip the last element because it is not 8 bytes
$chunks = array_slice(str_split($data, 8), 0, -1);
foreach ($chunks as $chunk) {
$hex64 = to_hex64($number);
$chunk_reencoded = hex64_to_chunk(chunk_to_hex64($chunk));
assert($chunk_reencoded == $chunk, "Result is $chunk_reencoded, expected $chunk");
}
Upvotes: 1
Reputation: 282915
I wrote a helper class for packing/unpacking 64-bit unsigned ints.
The relevant bit is just two lines:
$ints = unpack("@$offset/Vlo/Vhi", $data);
$sum = Math::add($ints['lo'], Math::mul($ints['hi'], '4294967296'));
(Math::*
is a simple wrapper around bcmath)
And packing:
$out .= pack('VV', (int)bcmod($args[$idx],'4294967296'), (int)bcdiv($args[$idx],'4294967296'));
It splits the 64-bit ints into two 32-bit ints, which 64-bit PHP should support :-)
Upvotes: 0