7

I am extracting a serial from a digital certificate using the built-in OpenSSL library, however, I am having trouble converting this number to hex with precision.

The extracted number is originally in decimal but I need to have it in hex.

The number I am trying to convert is: 114483222461061018757513232564608398004

Here is what I've tried:

  • dechex() did not work, it returns: 7fffffffffffffff

The closest I could get was this function from the php.net page but it does not convert the whole number on part of it.

function dec2hex($dec) {
  $hex = ($dec == 0 ? '0' : '');

  while ($dec > 0) {
    $hex = dechex($dec - floor($dec / 16) * 16) . $hex;
    $dec = floor($dec / 16);
  }

  return $hex;
}
echo dec2hex('114483222461061018757513232564608398004');
//Result: 5620aaa80d50fc000000000000000000

Here is what I am expecting:

  • Decimal number: 114483222461061018757513232564608398004
  • Expected hex: 5620AAA80D50FD70496983E2A39972B4

I can see the correction conversion here: https://www.mathsisfun.com/binary-decimal-hexadecimal-converter.html

I need a PHP solution.

MLavoie
  • 9,671
  • 41
  • 36
  • 56
user3436467
  • 1,763
  • 1
  • 22
  • 35
  • How do you obtain the number? Are you able to obtain it as a string (without casting)? – scrowler Aug 29 '16 at 04:24
  • here is the digital cert: http://pastebin.com/34Tgs6Lw `$cert = openssl_x509_parse($certdata);` then `echo $cert['serialNumber'];` – user3436467 Aug 29 '16 at 04:29

4 Answers4

8

The problem is that The largest number that can be converted is ... 4294967295 - hence why it's not working for you.

This answer worked for me during a quick test, assuming you have bcmath installed on your server, and you can obtain the number as a string to start with. If you can't, i.e. it begins life as numeric variable, you'll immediately reach PHP's float limit.

// Credit: joost at bingopaleis dot com
// Input: A decimal number as a String.
// Output: The equivalent hexadecimal number as a String.
function dec2hex($number)
{
    $hexvalues = array('0','1','2','3','4','5','6','7',
               '8','9','A','B','C','D','E','F');
    $hexval = '';
     while($number != '0')
     {
        $hexval = $hexvalues[bcmod($number,'16')].$hexval;
        $number = bcdiv($number,'16',0);
    }
    return $hexval;
}

Example:

$number = '114483222461061018757513232564608398004'; // Important: already a string!
var_dump(dec2hex($number)); // string(32) "5620AAA80D50FD70496983E2A39972B4"

Ensure you pass a string into that function, not a numeric variable. In the example you provided in the question, it looks like you can obtain the number as a string initially, so should work if you have bc installed.

scrowler
  • 24,273
  • 9
  • 60
  • 92
5

This is a big integer, so you need to use a big-integer library like GMP:

echo gmp_strval('114483222461061018757513232564608398004', 16);
// output: 5620aaa80d50fd70496983e2a39972b4
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
5

Answered by lafor. How to convert a huge integer to hex in php?

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

Example:
$decimal = '114483222461061018757513232564608398004';
echo "Hex decimal : ".bcdechex($decimal);
Community
  • 1
  • 1
Ganymede
  • 165
  • 2
  • 7
  • i remember seeing this before posting but it didnt work for me at the time.. I just installed bcmath and restarted apache and now it works – user3436467 Aug 29 '16 at 04:42
0

Try this 100% working for any number

 <?php 
        $dec = '114483222461061018757513232564608398004';
     // init hex array
       $hex = array();
       while ($dec)
       {
         // get modulus // based on docs both params are string
          $modulus = bcmod($dec, '16');
          // convert to hex and prepend to array
          array_unshift($hex, dechex($modulus));
         // update decimal number
         $dec = bcdiv(bcsub($dec, $modulus), 16);
        }
       // array elements to string
       echo implode('', $hex);

?>
Jinku
  • 21
  • 3