Large Hex Values with PHP Hexdec

Large hex values with PHP hexdec

As said on the hexdec manual page:

The function can now convert values
that are to big for the platforms
integer type, it will return the value
as float instead in that case.

If you want to get some kind of big integer (not float), you'll need it stored inside a string. This might be possible using BC Math functions.

For instance, if you look in the comments of the hexdec manual page, you'll find this note

If you adapt that function a bit, to avoid a notice, you'll get:

function bchexdec($hex)
{
$dec = 0;
$len = strlen($hex);
for ($i = 1; $i <= $len; $i++) {
$dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
}
return $dec;
}

(This function has been copied from the note I linked to; and only a bit adapted by me)

And using it on your number:

$h = 'D5CE3E462533364B';
$f = bchexdec($h);
var_dump($f);

The output will be:

string '15406319846273791563' (length=20)

So, not the kind of big float you had ; and seems OK with what you are expecting:

Result from calc.exe =
15406319846273791563


Hope this help ;-)

And, yes, user notes on the PHP documentation are sometimes a real gold mine ;-)

PHP - hexdec() function return float value for large numbers

That's beacuase int in PHP have a limit that depends if you are on a 32 or 64 bits system.

32bits: 2,147,483,647

64bits: 9,223,372,036,854,775,807

In this case you go beyond this limit and PHP convert it to a float.

Hexadecimal String Incrementation

Using functions from http://php.net/manual/en/ref.bc.php#99130

<?php

function bchexdec($hex) {
if(strlen($hex) == 1) {
return hexdec($hex);
} else {
$remain = substr($hex, 0, -1);
$last = substr($hex, -1);
return bcadd(bcmul(16, bchexdec($remain)), hexdec($last));
}
}

function bcdechex($dec) {
$last = bcmod($dec, 16);
$remain = bcdiv(bcsub($dec, $last), 16);

if($remain == 0) {
return dechex($last);
} else {
return bcdechex($remain).dechex($last);
}
}

echo bcdechex(bcadd(bchexdec('ffffffff000000000001586f'), 1));

https://3v4l.org/fXneg

Why does hexdec produce different results?

hexdec() assumes its’s getting a string. In the first you’re taking a number 0x80, which is 128 in decimal, and giving it to it. This means it needs to be made into a string “128” because the default way to convert is the decimal form. When you then want that to be treated as hex it will become 296.

In the last one you actually say “here’s a string of a hex number, convert it to decimal” and the conversion is done.

Numeric literals aren’t handled as hex or dec or anything. They’re just numbers and hexdec() isn’t meant to be used with them. Only strings. This is where implicit conversions between types may cause issues.

PHP hexdec. How to avoid unexpected round down?

You should use GMP functions:

GMP gmp_init ( mixed $number [, int $base = 0 ] )

For your issue:

echo gmp_init ( '6252f8774def5e344',16);

Solution like this base_convert('6252f8774def5e344', 16, 10) will not work =>
php.net: base-convert

base_convert() may lose precision on large numbers due to properties related to the internal "double" or "float" type used. Please see the Floating point numbers section in the manual for more specific information and limitations.

PHP convert large Decimal number to Hexadecimal

Your SerialNumber is a Math_BigInteger object as the var_dump shows.
Use the toHex method to retrieve the contained number in a hexadecimal format.
See reference on PEAR website.

$serial = $cert['tbsCertificate']['serialNumber'];
$valueInHex = $serial->toHex();

Note: 118045041395046077749311747456482878735 in decimal format equals to 58CEA5E36351B91F49E47A20CEFF250F in hexadecimal format. You may easily check that with an online converter like this.

How to convert a huge integer to hex in php?

It's pretty easy to modify the function you found to be iterative rather than recursive:

function bcdechex($dec) {
$hex = '';
do {
$last = bcmod($dec, 16);
$hex = dechex($last).$hex;
$dec = bcdiv(bcsub($dec, $last), 16);
} while($dec>0);
return $hex;
}

Your example $bignum converted to hex is:
b1cf5653e79bef001acfb0f99d1f34487d16a8253e3a9971e98d46382114e8ac81b5102ab3c56be1f77d0eb754f566c0dacb23d64755e823f35411f9e14c5617



Related Topics



Leave a reply



Submit