When I try to find collision in a hash value using php, there is a problem. I can find the first 3 byte collision successfully. However when I try to find the 10 byte collision the array_search does not work. It return some non match value to me. Can anyone help me? Here is my code.
<?php
$array = array();
$do = true;
do {
$num1= rand(1,90000);
$num2= rand(1,90000);
$testcase2 = $num1."14040371D".$num2;
$testcase1 = (string)$testcase2;
$hashed = (string)substr(sha1($testcase1),0,10);
//echo($testcase1."
");
$findornot = array_search($hashed,$array);
if($findornot !== false) {
$array[$testcase1] = $hashed;
echo ($findornot."
");
echo ($testcase1."
");
echo ($hashed);
$do=false;
} else {
$array[$testcase1] = $hashed;
}
//print_r(array_values($array));
}while($do)
?>
TL;DR
$findornot = array_search($hashed, $array, true);
Fixed.
Explanation:
You're not going crazy.
The key is "strict comparison" - you've correctly type casted in a few places, and used ===
for your own comparisons.
You need array_search
to do the same thing. Otherwise a string like 0e1
will match 0e2
according to array_search
.
The third parameter to array_search
is an optional boolean to force strict comparison. Turn that on, and your problem will go away.
Update (to prove)
Proof code (input):
<?php
$a = "2e1";
$b = "2e2";
var_dump($a == $b);
var_dump($a === $b);
var_dump($a == "20");
var_dump($a === "20");
Proof output:
bool(false)
bool(false)
bool(true)
bool(false)
PHP is seeing the 'e' character surrounded by numeric digits and is treating it as a exponential when type-juggling to an integer.
It's one of PHP's best features, and one of its greatest failings IMHO. Ah well! Anyone up for coding in C?