Search code examples
phptype-conversiongmphmac

Why is hash_hmac making different hashes for these two large numbers?


Why are hmac values different ? $a is equal to $b. I'm not sure what kind of error is causing this or if my logic is correct. Hmac_hash should convert any input to string to byte or hex and do it's job, tell me if I'm wrong.

Below example code.

Thank you.

<?php

$a = 1234567890000*1234567890000;
$b = gmp_mul("1234567890000","1234567890000");
$b = gmp_strval($b);

echo $a."<br/>".$b."<br/>";

$c = 2525;

echo ($a==$b)."<br/>";

echo hash_hmac("SHA512",$a,$c);
echo "<br/>";
echo hash_hmac("SHA512",$b,$c);

?> 

Result

1.5241578750191E+24
1524157875019052100000000
1
973967436d3562150d60769b70a9010db21f89b114b9897430663dd195115b7893b9a6bd0e141cee301d23e2229afd6d39546630cd38f6fe7842073749f9ce3d
8bd1e7c837efaf8d51ed2d40354a020ee3c9663aa6bd4425c02b21ed02343185070216d37e54478ee78332af8e6fdecd51445fcee8cb04d4e51e4cc31283f9a9

Solution

  • When you compare $a and $b, the string inside $b is converted into an integer. Because the value is larger than what PHP can represent as an integer, it gets silently converted into a float instead. $a is a float. The floats are equal, which is why the compare succeeds.

    hash_hmac converts the float in $a to a string instead of converting the string in $b into an integer which then overflows into a float. This is why the hashes differ.

    If you want the compare to fail so that the behavior between it and hash_hmac is consistent, you'll want to cast $a into a string first or will want to use === to avoid converting data types.