user263078
user263078

Reputation:

PHP script to find if an MD5 hashes to itself?

This is basically a hypothetical program- there are 2^128 combinations (Or is it 2^128-1? Not sure. Or should the 128 be replaced with a 127?) but it doesn't work.

<?php

$end = (int)base_convert("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",36,10);
$count = 0;
for($count = 0; $count < $end; $count++) {
    $startHash = base_convert((string)$count,10,36);
    //Add zeros to the beginning if the length is less than 32
    while(strlen($starthash) < 32) {
        $starthash = "0" + $startHash;
    }
    $endHash = md5($startHash);
    if($startHash == $endHash) {
        file_put_contents("MD5.txt", file_get_contents("MD5.txt") + $startHash + "\n");
    }
}

?>

I'm not even sure why; it doesn't even throw any errors. What I'm expecting is that it uses 100% of the CPU, but it doesn't use more than 0.1%.

Do you have any idea what's going on?

Upvotes: 1

Views: 575

Answers (3)

GolezTrol
GolezTrol

Reputation: 116100

Like Mike says, your casing is wrong. But besides that, an md5 hash is actually a 16 character value which is often represented in 32 bytes to let it consist of only letters and numbers. It will, in that case, always consist of numbers 0 to 9 and letters A to F (or is it a to f?), so you actually only need to check for those. You now make the wrong assumption that the 32 character md5 code is a base 36 number.

The md5 function has a second parameter that allows you to get the 16 byte raw code.

Another problem you may face is that PHP is not so fast and usually has a time-out. It may be better to write a program in a different language, add some threading, and save the value regularly, so you can resume the program after shutdown.

[edit] Maybe this will give you an idea of how long to wait. md5 = 16 bytes = 4 integer with a maximum of 4 billion ($FFFFFFFF) each. So to loop through all values of these 16 bytes, you need to nest four for loops that each run to 4 billion:

<?
for($a = 0; $a <= 0xFFFFFFFF; $a++){
    for($b = 0; $b <= 0xFFFFFFFF; $b++){
        for($c = 0; $d <= 0xFFFFFFFF; $c++){
            for($d = 0; $d <= 0xFFFFFFFF; $d++){
                $code = 
                    str_pad(dechex($a), 8, "0", STR_PAD_LEFT).
                    str_pad(dechex($b), 8, "0", STR_PAD_LEFT).
                    str_pad(dechex($c), 8, "0", STR_PAD_LEFT).
                    str_pad(dechex($d), 8, "0", STR_PAD_LEFT);
                $md5code = md5($code);
                if ($code == $md5code)
                {
                    echo $code . "\n"; // Found one
                }
            }
        }
    }
}
echo 'done';

Upvotes: 1

mario
mario

Reputation: 145482

Your loop variable $count is an ordinary PHP integer. It will never grow to 128 bits. You should use a binary string or better yet:

$end = gmp_init("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
$count = gmp_init("0");

for ( ; gmp_cmp($count, $end) == 0; $count=gmp_add($count, 1)) {

And it seems you are trying to see if the hex representation of the hash hashes to itself. So you should gmp+base_convert to 16 maybe.

Finally try file_put_contents($fn, $data, FILE_APPEND)

I doubt you'll get an result however. Even if CPU usage should increase.

Upvotes: 1

Mike
Mike

Reputation: 923

The main problem I see is that you aren't consistent with the case of $startHash. Variables in php are case-sensitive.

Upvotes: 1

Related Questions