I only understood (or think I understood) two pieces of that - the rest was simply incoherent.
f they don't covered all the 32 hex string, this means md5 cannot hash up to 1632 hashes. maybe can only hash less than 1632 hashes
.
MD5 can generate a hash for any sequence of binary data, hashes included. So I guess that is supposed to mean "maybe not every sequence of 128 bits is an MD5 hash of some string".
I don't have a cast-iron proof on hand, but looking at the reference implementation in rfc1321, I see no operation that would restrict MD5 to a portion of 128-bit space. The simpler operations and functions are able to generate any desired sequence of 32 bits given appropriate inputs, at least. 'Course, Rivest is more experienced at this sort of thing than me.
Then again, MD5 space could be less than 1% of 128-bit space, and still leave enough real hashes to uniquely identify every book, album, and movie ever published by human beings up to the present day. And have enough left over to individually hash every grain of sand in the solar system.
i am planning to construct a md5 function using php script...
anyone wanna join..?
so, we will understand the implementation of md5 better.
Something like this?
function dh($num)
{ $hex_chr = "0123456789abcdef";
return $hex_chr{(($num >> 4) & 0xf)}.$hex_chr{(($num >> 0) & 0xf)}
. $hex_chr{(($num >> 12) & 0xf)}.$hex_chr{(($num >> 8) & 0xf)}
. $hex_chr{(($num >> 20) & 0xf)}.$hex_chr{(($num >> 16) & 0xf)}
. $hex_chr{(($num >> 28) & 0xf)}.$hex_chr{(($num >> 24) & 0xf)};
}
function str2blks($str)
{
$nblk = ((strlen($str) + 8) >> 6) + 1;
$blks = array_fill(0,$nblk<<4,0);
for($i = 0; $i < strlen($str); $i++)
$blks[$i >> 2] |= ord($str{$i}) << (($i & 3) << 3);
$blks[$i >> 2] |= 0x80 << (($i & 3) << 3);
$blks[($nblk << 4) - 2] = strlen($str) << 3;
return $blks;
}
function add($x,$y)
{ return (($x&0x7fffffff)+($y&0x7fffffff))^($x&0x80000000)^($y&0x80000000);
}
function rol($num,$cnt)
{ $b = substr('00000000000000000000000000000000'.decbin($num),-32);
return bindec(substr($b,$cnt).substr($b,0,$cnt));
}
function cmp($f, $a, $b, $x, $s, $ac)
{ return add(rol(add(add($a, $f), add($x, $ac)), $s), $b);
}
function ff($a, $b, $c, $d, $x, $s, $t)
{ return cmp((($b & $c) | ((~$b) & $d)), $a, $b, $x, $s, $t);
}
function gg($a, $b, $c, $d, $x, $s, $t)
{ return cmp((($b & $d) | ($c & (~$d))), $a, $b, $x, $s, $t);
}
function hh($a, $b, $c, $d, $x, $s, $t)
{ return cmp(($b ^ $c ^ $d), $a, $b, $x, $s, $t);
}
function ii($a, $b, $c, $d, $x, $s, $t)
{ return cmp(($c ^ ($b | (~$d))), $a, $b, $x, $s, $t);
}
function MD5_($str)
{ $x = str2blks($str);
$a = 0x67452301;
$b = 0xefcdab89;
$c = 0x98badcfe;
$d = 0x10325476;
for($i=0; $i<count($x); $i+=16)
{ $olda = $a;
$oldb = $b;
$oldc = $c;
$oldd = $d;
$a = ff($a, $b, $c, $d, $x[$i+ 0], 7 , 0xd76aa478);
$d = ff($d, $a, $b, $c, $x[$i+ 1], 12, 0xe8c7b756);
$c = ff($c, $d, $a, $b, $x[$i+ 2], 17, 0x242070db);
$b = ff($b, $c, $d, $a, $x[$i+ 3], 22, 0xc1bdceee);
$a = ff($a, $b, $c, $d, $x[$i+ 4], 7 , 0xf57c0faf);
$d = ff($d, $a, $b, $c, $x[$i+ 5], 12, 0x4787c62a);
$c = ff($c, $d, $a, $b, $x[$i+ 6], 17, 0xa8304613);
$b = ff($b, $c, $d, $a, $x[$i+ 7], 22, 0xfd469501);
$a = ff($a, $b, $c, $d, $x[$i+ 8], 7 , 0x698098d8);
$d = ff($d, $a, $b, $c, $x[$i+ 9], 12, 0x8b44f7af);
$c = ff($c, $d, $a, $b, $x[$i+10], 17, 0xffff5bb1);
$b = ff($b, $c, $d, $a, $x[$i+11], 22, 0x895cd7be);
$a = ff($a, $b, $c, $d, $x[$i+12], 7 , 0x6b901122);
$d = ff($d, $a, $b, $c, $x[$i+13], 12, 0xfd987193);
$c = ff($c, $d, $a, $b, $x[$i+14], 17, 0xa679438e);
$b = ff($b, $c, $d, $a, $x[$i+15], 22, 0x49b40821);
$a = gg($a, $b, $c, $d, $x[$i+ 1], 5 , 0xf61e2562);
$d = gg($d, $a, $b, $c, $x[$i+ 6], 9 , 0xc040b340);
$c = gg($c, $d, $a, $b, $x[$i+11], 14, 0x265e5a51);
$b = gg($b, $c, $d, $a, $x[$i+ 0], 20, 0xe9b6c7aa);
$a = gg($a, $b, $c, $d, $x[$i+ 5], 5 , 0xd62f105d);
$d = gg($d, $a, $b, $c, $x[$i+10], 9 , 0x02441453);
$c = gg($c, $d, $a, $b, $x[$i+15], 14, 0xd8a1e681);
$b = gg($b, $c, $d, $a, $x[$i+ 4], 20, 0xe7d3fbc8);
$a = gg($a, $b, $c, $d, $x[$i+ 9], 5 , 0x21e1cde6);
$d = gg($d, $a, $b, $c, $x[$i+14], 9 , 0xc33707d6);
$c = gg($c, $d, $a, $b, $x[$i+ 3], 14, 0xf4d50d87);
$b = gg($b, $c, $d, $a, $x[$i+ 8], 20, 0x455a14ed);
$a = gg($a, $b, $c, $d, $x[$i+13], 5 , 0xa9e3e905);
$d = gg($d, $a, $b, $c, $x[$i+ 2], 9 , 0xfcefa3f8);
$c = gg($c, $d, $a, $b, $x[$i+ 7], 14, 0x676f02d9);
$b = gg($b, $c, $d, $a, $x[$i+12], 20, 0x8d2a4c8a);
$a = hh($a, $b, $c, $d, $x[$i+ 5], 4 , 0xfffa3942);
$d = hh($d, $a, $b, $c, $x[$i+ 8], 11, 0x8771f681);
$c = hh($c, $d, $a, $b, $x[$i+11], 16, 0x6d9d6122);
$b = hh($b, $c, $d, $a, $x[$i+14], 23, 0xfde5380c);
$a = hh($a, $b, $c, $d, $x[$i+ 1], 4 , 0xa4beea44);
$d = hh($d, $a, $b, $c, $x[$i+ 4], 11, 0x4bdecfa9);
$c = hh($c, $d, $a, $b, $x[$i+ 7], 16, 0xf6bb4b60);
$b = hh($b, $c, $d, $a, $x[$i+10], 23, 0xbebfbc70);
$a = hh($a, $b, $c, $d, $x[$i+13], 4 , 0x289b7ec6);
$d = hh($d, $a, $b, $c, $x[$i+ 0], 11, 0xeaa127fa);
$c = hh($c, $d, $a, $b, $x[$i+ 3], 16, 0xd4ef3085);
$b = hh($b, $c, $d, $a, $x[$i+ 6], 23, 0x04881d05);
$a = hh($a, $b, $c, $d, $x[$i+ 9], 4 , 0xd9d4d039);
$d = hh($d, $a, $b, $c, $x[$i+12], 11, 0xe6db99e5);
$c = hh($c, $d, $a, $b, $x[$i+15], 16, 0x1fa27cf8);
$b = hh($b, $c, $d, $a, $x[$i+ 2], 23, 0xc4ac5665);
$a = ii($a, $b, $c, $d, $x[$i+ 0], 6 , 0xf4292244);
$d = ii($d, $a, $b, $c, $x[$i+ 7], 10, 0x432aff97);
$c = ii($c, $d, $a, $b, $x[$i+14], 15, 0xab9423a7);
$b = ii($b, $c, $d, $a, $x[$i+ 5], 21, 0xfc93a039);
$a = ii($a, $b, $c, $d, $x[$i+12], 6 , 0x655b59c3);
$d = ii($d, $a, $b, $c, $x[$i+ 3], 10, 0x8f0ccc92);
$c = ii($c, $d, $a, $b, $x[$i+10], 15, 0xffeff47d);
$b = ii($b, $c, $d, $a, $x[$i+ 1], 21, 0x85845dd1);
$a = ii($a, $b, $c, $d, $x[$i+ 8], 6 , 0x6fa87e4f);
$d = ii($d, $a, $b, $c, $x[$i+15], 10, 0xfe2ce6e0);
$c = ii($c, $d, $a, $b, $x[$i+ 6], 15, 0xa3014314);
$b = ii($b, $c, $d, $a, $x[$i+13], 21, 0x4e0811a1);
$a = ii($a, $b, $c, $d, $x[$i+ 4], 6 , 0xf7537e82);
$d = ii($d, $a, $b, $c, $x[$i+11], 10, 0xbd3af235);
$c = ii($c, $d, $a, $b, $x[$i+ 2], 15, 0x2ad7d2bb);
$b = ii($b, $c, $d, $a, $x[$i+ 9], 21, 0xeb86d391);
$a = add($a, $olda);
$b = add($b, $oldb);
$c = add($c, $oldc);
$d = add($d, $oldd);
}
$a = substr('00000000'.dh($a),-8);
$b = substr('00000000'.dh($b),-8);
$c = substr('00000000'.dh($c),-8);
$d = substr('00000000'.dh($d),-8);
return $a.$b.$c.$d;
}
//test
echo MD5_("") . ' ' . strcmp(MD5_(""),md5("")) . "\n";
echo MD5_("a") . ' ' . strcmp(MD5_("a"),md5("a")) . "\n";
echo MD5_("abc") . ' ' . strcmp(MD5_("abc"),md5("abc")) . "\n";
echo MD5_("message digest") . ' ' . strcmp(MD5_("message digest"),md5("message digest")) . "\n";
echo MD5_("abcdefghijklmnopqrstuvwxyz") . ' ' . strcmp(MD5_("abcdefghijklmnopqrstuvwxyz"),md5("abcdefghijklmnopqrstuvwxyz")) . "\n";
echo MD5_("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") . ' ' . strcmp(MD5_("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")) . "\n";
echo MD5_("12345678901234567890123456789012345678901234567890123456789012345678901234567890") . ' ' . strcmp(MD5_("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),md5("12345678901234567890123456789012345678901234567890123456789012345678901234567890")) . "\n";
Of course, you'd probably understand it better if you wrote it yourself. The reference implementation is a good place to start.
I still don't understand any of the rest of that post - what the significance of md5(md5(md5(....))) is supposed to be in this context or what it's supposed to prove (the topology of the thing might be interesting for its own sake, but the same could be said of most other discrete dynamical systems - most of which would be far less artificial).