# Implement the MD5 algorithm! [closed]

Your challenge is to output the MD5 hash of your input. The specification of MD5 can be found here. Crypto builtins are NOT allowed. Shortest code wins. Psuedocode:

//Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
var int[64] s, K

//s specifies the per-round shift amounts
s[ 0..15] := { 7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22 }
s[16..31] := { 5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20 }
s[32..47] := { 4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23 }
s[48..63] := { 6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21 }

//Use binary integer part of the sines of integers (Radians) as constants:
for i from 0 to 63
K[i] := floor(232 × abs(sin(i + 1)))
end for
//(Or just use the following precomputed table):
K[ 0.. 3] := { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee }
K[ 4.. 7] := { 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 }
K[ 8..11] := { 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be }
K[12..15] := { 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 }
K[16..19] := { 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa }
K[20..23] := { 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 }
K[24..27] := { 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed }
K[28..31] := { 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a }
K[32..35] := { 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c }
K[36..39] := { 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 }
K[40..43] := { 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 }
K[44..47] := { 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 }
K[48..51] := { 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 }
K[52..55] := { 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 }
K[56..59] := { 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 }
K[60..63] := { 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }

//Initialize variables:
var int a0 := 0x67452301   //A
var int b0 := 0xefcdab89   //B
var int c0 := 0x98badcfe   //C
var int d0 := 0x10325476   //D

//Pre-processing: adding a single 1 bit
append "1" bit to message
// Notice: the input bytes are considered as bits strings,
//  where the first bit is the most significant bit of the byte.[49]

append "0" bit until message length in bits ≡ 448 (mod 512)
append original length in bits mod (2 pow 64) to message

//Process the message in successive 512-bit chunks:
for each 512-bit chunk of message
break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15
//Initialize hash value for this chunk:
var int A := a0
var int B := b0
var int C := c0
var int D := d0
//Main loop:
for i from 0 to 63
if 0 ≤ i ≤ 15 then
F := (B and C) or ((not B) and D)
g := i
else if 16 ≤ i ≤ 31
F := (D and B) or ((not D) and C)
g := (5×i + 1) mod 16
else if 32 ≤ i ≤ 47
F := B xor C xor D
g := (3×i + 5) mod 16
else if 48 ≤ i ≤ 63
F := C xor (B or (not D))
g := (7×i) mod 16
//Be wary of the below definitions of a,b,c,d
dTemp := D
D := C
C := B
B := B + leftrotate((A + F + K[i] + M[g]), s[i])
A := dTemp
end for
//Add this chunk's hash to result so far:
a0 := a0 + A
b0 := b0 + B
c0 := c0 + C
d0 := d0 + D
end for

var char digest[16] := a0 append b0 append c0 append d0 //(Output is in little-endian)

//leftrotate function definition
leftrotate (x, c)
return (x << c) binary or (x >> (32-c));

• Linking to an RFC isn't really sufficient, see the relevant sha256 question. – FryAmTheEggman Jun 11 '17 at 20:30
• I don't particularly like this challenge, simply because it decays to "Which language has the shortest built-in for MD5 hashing?" Although the general consensus in the past has been not to bar built-ins, I think in this case a better question would prohibit crypto builtins. – musicman523 Jun 11 '17 at 20:40
• Ok, that's cool, just change the restrictions, invalidating 4 answers. – Conor O'Brien Jun 11 '17 at 20:42
• This is the type of feedback that should be caught in the Sandbox – musicman523 Jun 11 '17 at 20:44
• It is unadvisable to make a trivial challenge and then change the specifications. Having a challenge that is literally "give me the shortest MD5 builtin" is bound to get many answers very quickly, and then changing the specifications and invalidating all of them is not a good idea. Additionally, this sort of stuff would have been caught in the Sandbox; even if the Sandbox seems very obselete now, linking it into chat and having a few people see it would have been enough to get this feedback. – HyperNeutrino Jun 11 '17 at 20:55

# PHP, 3012 bytes

removing unnessary Whitespaces and short some variables and function names and replacing string with non existing constants

function MD($s){$A=$a="67452301";$B=$b=efcdab89;$C=$c="98badcfe";$D=$d="10325476";$words=str2blks_MD5($s);$z=[A,B,C,D];$it=[7,12,17,22,5,9,14,20,4,11,16,23,6,10,15,21];$funcs=[F,G,H,I];$moduls=[0,1,1,5,5,3,0,7];$acs=[d76aa478,e8c7b756,"242070db",c1bdceee,f57c0faf,"4787c62a",a8304613,fd469501,"698098d8","8b44f7af",ffff5bb1,"895cd7be","6b901122",fd987193,a679438e,"49b40821",f61e2562,c040b340,"265e5a51",e9b6c7aa,d62f105d,"2441453",d8a1e681,e7d3fbc8,"21e1cde6",c33707d6,f4d50d87,"455a14ed",a9e3e905,fcefa3f8,"676f02d9","8d2a4c8a",fffa3942,"8771f681","6d9d6122",fde5380c,a4beea44,"4bdecfa9",f6bb4b60,bebfbc70,"289b7ec6",eaa127fa,d4ef3085,"4881d05",d9d4d039,e6db99e5,"1fa27cf8",c4ac5665, f4292244,"432aff97",ab9423a7,fc93a039,"655b59c3","8f0ccc92",ffeff47d,"85845dd1","6fa87e4f",fe2ce6e0,a3014314,"4e0811a1",f7537e82,bd3af235,"2ad7d2bb",eb86d391];for($i=0;$i<count($words)/16;$i++){$a=$A;$b=$B;$c=$C;$d=$D;$n=0;for($rot3=0;$rot3<4;$rot3++){$minit=$moduls[$rot3*2];$madd=$moduls[$rot3*2+1];for($rot2=0;$rot2<4;$rot2++){for ($rot=0;$rot<4;$rot++){$word=$words[$minit+($i*16)];$nit=$it[$rot+4*$rot3];FGHI(${"$z[0]"},${"$z[1]"},${"$z[2]"},${"$z[3]"},$word,$nit,$acs[$n],$funcs[$rot3]);array_unshift($z,$z[3]);array_pop($z);$minit=($minit+$madd)%16;++$n;}}}$A=_A(_X($A),_X($a));$B=_A(_X($B),_X($b));$C=_A(_X($C),_X($c));$D=_A(_X($D),_X($d));}return _W($A)._W($B)._W($C)._W($D);}function _W($lValue){$_WValue="";for($lCount=0;$lCount<4;$lCount++){$lByte=_X($lValue)>>($lCount*8)&255;$_WValue.=sprintf("%02x",$lByte);}return$_WValue;}function FGHI(&$A,$B,$C,$D,$M,$s,$t,$func){$Level1=_X(_A(FGHI2($B,$C,$D,$func),bindec($M)));$level2=_X(_A($Level1, _X($t)));$A=_X(_A(_X($A),$level2));$A=rotate($A,$s);$A=_A($A,_X($B));}function FGHI2($X,$Y,$Z,$func){$X=_X($X);$Y=_X($Y);$Z=_X($Z);switch($func){case F:$calc=(($X&$Y)|((~$X)&$Z));break;case G:$calc=(($X&$Z)|($Y&(~$Z)));break;case H:$calc=($X^$Y^$Z);break;case I:$calc=($Y^($X|(~$Z)));}return$calc;}function dectohex($res){if($res<0)return'-'.dechex(abs($res));return dechex($res);}function _X($hex){if($hex[0]=="-")return doubleval('-'.hexdec(str_replace("-","",$hex)));return hexdec($hex);}function _A($lX,$lY){ $lX8=($lX&0x80000000);$lY8=($lY&0x80000000);$lX4=($lX&0x40000000);$lY4=($lY&0x40000000);$lResult=($lX&0x3FFFFFFF)+($lY&0x3FFFFFFF);$res=$lResult^$lX8^$lY8;if($lX4&$lY4)return dectohex($res^0x80000000);if($lX4|$lY4){if($lResult&0x40000000)return dectohex($res^0xC0000000);else return dectohex($res^0x40000000);}return dectohex($res);}function rotate($_d,$bits){return(($_d<<$bits)|shiftright($_d,(32-$bits))&0xffffffff);}function shiftright($_d,$right){$shift=$_d>>$right;if($_d>=0)return$shift;return bindec(substr(decbin($shift),$right));}function str2blks_MD5($s){$nblk=((strlen($s)+8)>>6)+1;$blks=[$nblk*16];for($i=0;$i<$nblk*16;$i++)$blks[$i]=0;for($i=0;$i<strlen($s);$i++)$blks[$i>>2]|=ord($s[$i])<<(($i%4)*8);$blks[$i>>2]|=0x80<<(($i%4)*8);$blks[$nblk*16-2]=strlen($s)*8;for($i=0;$i<$nblk*16;$i++)$blks[$i]=decbin($blks[$i]);return$blks;}echo MD($argn);  Try it online! # PHP, 5307 bytes copy and paste from here function MD($string)
{
$A =$a = "67452301";
$B =$b = "efcdab89";
$C =$c = "98badcfe";
$D =$d = "10325476";

$words = str2blks_MD5($string);

$torot=array("A","B","C","D");$it=array(7,12,17,22,5,9,14,20,4,11,16,23,6,10,15,21);
$funcs=array("F","G","H","I");$moduls=array(0,1,1,5,5,3,0,7);

$acs=array( "d76aa478","e8c7b756","242070db","c1bdceee", "f57c0faf","4787c62a","a8304613","fd469501", "698098d8","8b44f7af","ffff5bb1","895cd7be", "6b901122","fd987193","a679438e","49b40821", "f61e2562","c040b340","265e5a51","e9b6c7aa", "d62f105d","2441453","d8a1e681","e7d3fbc8", "21e1cde6","c33707d6","f4d50d87","455a14ed", "a9e3e905","fcefa3f8","676f02d9","8d2a4c8a", "fffa3942","8771f681","6d9d6122","fde5380c", "a4beea44","4bdecfa9","f6bb4b60","bebfbc70", "289b7ec6","eaa127fa","d4ef3085","4881d05", "d9d4d039","e6db99e5","1fa27cf8","c4ac5665", "f4292244","432aff97","ab9423a7","fc93a039", "655b59c3","8f0ccc92","ffeff47d","85845dd1", "6fa87e4f","fe2ce6e0","a3014314","4e0811a1", "f7537e82","bd3af235","2ad7d2bb","eb86d391"); for($i = 0; $i < count($words)/16; $i++) {$a  = $A;$b  = $B;$c  = $C;$d  = $D;$n  = 0;

for ($rot3=0;$rot3<4;$rot3++) {$minit=$moduls[$rot3*2];
$madd=$moduls[$rot3*2+1]; for ($rot2=0;$rot2<4;$rot2++)
{
for ($rot=0;$rot<4;$rot++) {$word=$words[$minit + ($i * 16)];$nit=$it[$rot+4*$rot3]; FGHI (${"$torot[0]"},${"$torot[1]"},${"$torot[2]"},${"$torot[3]"},$word, $nit,$acs[$n],$funcs[$rot3]); array_unshift($torot,$torot[3]); array_pop($torot);

$minit=($minit+$madd)%16; ++$n;
}
}
}

$A=AddUnsigned(hexdec2($A),hexdec2($a));$B=AddUnsigned(hexdec2($B),hexdec2($b));
$C=AddUnsigned(hexdec2($C),hexdec2($c));$D=AddUnsigned(hexdec2($D),hexdec2($d));
}
return WordToHex($A).WordToHex($B).WordToHex($C).WordToHex($D);
}
function WordToHex($lValue) {$WordToHexValue = "";
for ($lCount = 0;$lCount<4;$lCount++) {$lByte = hexdec2($lValue)>>($lCount*8) & 255;
$WordToHexValue.= sprintf("%02x",$lByte);
}
return $WordToHexValue; } function FGHI(&$A, $B,$C, $D,$M, $s,$t, $func) {$Level1 = hexdec2(AddUnsigned(FGHI2($B,$C, $D,$func) , bindec($M) ));$level2 = hexdec2(AddUnsigned($Level1, hexdec2($t)));
$A = hexdec2(AddUnsigned(hexdec2($A),$level2));$A = rotate($A,$s);
$A = AddUnsigned($A , hexdec2($B)) ; } function FGHI2($X, $Y,$Z,$func) {$X = hexdec2($X);$Y = hexdec2($Y);$Z = hexdec2($Z); switch ($func)
{
case "F":
$calc = (($X & $Y) | ((~$X) & $Z));break; case "G":$calc = (($X &$Z) | ($Y & (~$Z)));break;
case "H":
$calc = ($X ^ $Y ^$Z);break;
case "I":
$calc = ($Y ^ ($X | (~$Z)));
}
return  $calc; } function dectohex($res)
{
if($res < 0) return '-'.dechex(abs($res));
return dechex($res); } function hexdec2($hex)
{
if($hex[0] == "-") return doubleval('-'.hexdec(str_replace("-", "",$hex )));

return hexdec($hex); } function AddUnsigned($lX,$lY) {$lX8 = ($lX & 0x80000000);$lY8 = ($lY & 0x80000000);$lX4 = ($lX & 0x40000000);$lY4 = ($lY & 0x40000000);$lResult = ($lX & 0x3FFFFFFF)+($lY & 0x3FFFFFFF);

$res=$lResult ^ $lX8 ^$lY8;

if ($lX4 &$lY4)                       return dectohex($res ^ 0x80000000); if ($lX4 | $lY4) { if ($lResult & 0x40000000)         return dectohex($res ^ 0xC0000000); else return dectohex($res ^ 0x40000000);
}                                  return dectohex($res); } function rotate ($decimal, $bits) { return (($decimal << $bits) | shiftright($decimal, (32 - $bits)) & 0xffffffff); } function shiftright($decimal , $right) {$shift=$decimal >>$right;

if($decimal >= 0) return$shift;
return bindec(substr(decbin($shift),$right));
}

function str2blks_MD5($str) {$nblk = ((strlen($str) + 8) >> 6) + 1;$blks = array($nblk * 16); for($i = 0; $i <$nblk * 16; $i++)$blks[$i] = 0; for($i = 0; $i < strlen($str); $i++)$blks[$i >> 2] |= ord($str[$i]) << (($i % 4) * 8);

$blks[$i >> 2] |= 0x80 << (($i % 4) * 8);$blks[$nblk * 16 - 2] = strlen($str) * 8;

for ($i=0;$i < $nblk * 16;$i++)
$blks[$i] = decbin($blks[$i]);

return $blks; } echo MD($argn);


Try it online!