PHP has a couple of functions to convert integers to hexadecimal, dechex() and base_convert(). However, both functions lose precision on large integers.
For example:
$bigint_hash = '11442725345190069619'; $hexadecimal_hash = '9eccba134669c573'; $converted_hash = dechex( $bigint_hash+0 ); //+0 just makes sure a float is passed to function echo 'Decimal value is: '. $bigint_hash. "/n"; echo 'Hexidecimal value SHOULD be : '. $hexadecimal_hash. "/n"; echo 'Hexidecimal value converts to: '. $converted_hash. "/n"; //outputs /* Decimal value is: 11442725345190069619 Hexidecimal value SHOULD be : 9eccba134669c573 Hexidecimal value converts to: 9eccba134669c800 */
There are PHP solutions that allow you to create an alternative to dechex()
/ base_convert( $num, 16, 10 )
with more accuracy but they require BC Math or GMP extensions to be installed.
A colleague of mine passed on an alternative to dechex()
or base_convert( $num, 16, 10 )
that was apparently listed on php.net but was removed due (I’m guessing!) to some bad language filter despite how semantically accurate the function’s naming convention uses.
Here it is:
/* Follows the syntax of base_convert (http://www.php.net/base_convert) * Created by Michael Renner @ http://www.php.net/base_convert 17-May-2006 03:24 * His comment is has since been deleted. The function will tell you why. */ function unfucked_base_convert($numstring, $frombase, $tobase) { $chars = "0123456789abcdefghijklmnopqrstuvwxyz"; $tostring = substr($chars, 0, $tobase); $length = strlen($numstring); $result = ''; for ($i = 0; $i < $length; $i++) { $number[$i] = strpos($chars, $numstring{$i}); } do { $divide = 0; $newlen = 0; for ($i = 0; $i < $length; $i++) { $divide = $divide * $frombase + $number[$i]; if ($divide >= $tobase) { $number[$newlen++] = (int)($divide / $tobase); $divide = $divide % $tobase; } elseif ($newlen > 0) { $number[$newlen++] = 0; } } $length = $newlen; $result = $tostring{$divide} . $result; } while ($newlen != 0); return $result; }
The source can be found on GitHub.
Now I can convert with freedom:
$bigint_hash = '11442725345190069619'; $hexadecimal_hash = '9eccba134669c573'; $converted_hash = unfucked_base_convert( $bigint_hash, 16, 10 ); echo 'Decimal value is: '. $bigint_hash. "/n"; echo 'Hexidecimal value SHOULD be : '. $hexadecimal_hash. "/n"; echo 'Hexidecimal value converts to: '. $converted_hash. "/n"; //outputs /* Decimal value is: 11442725345190069619 Hexidecimal value SHOULD be : 9eccba134669c573 Hexidecimal value converts to: 9eccba134669c573 */
Hello from Athens in Greece
My friend this function is a REAL work of (software) art
Is REALLY awsome
Thank you for sharing it.
Christos
Software engineer
(retired but ALWAYS a software engineer.. lol)