-5
\$\begingroup\$

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]


//Pre-processing: padding with zeros
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));
\$\endgroup\$

closed as too broad by MilkyWay90, Embodiment of Ignorance, Sriotchilism O'Zaic, NoOneIsHere, mbomb007 Mar 24 at 0:20

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 4
    \$\begingroup\$ Linking to an RFC isn't really sufficient, see the relevant sha256 question. \$\endgroup\$ – FryAmTheEggman Jun 11 '17 at 20:30
  • 3
    \$\begingroup\$ 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. \$\endgroup\$ – musicman523 Jun 11 '17 at 20:40
  • 7
    \$\begingroup\$ Ok, that's cool, just change the restrictions, invalidating 4 answers. \$\endgroup\$ – Conor O'Brien Jun 11 '17 at 20:42
  • 7
    \$\begingroup\$ This is the type of feedback that should be caught in the Sandbox \$\endgroup\$ – musicman523 Jun 11 '17 at 20:44
  • 4
    \$\begingroup\$ 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. \$\endgroup\$ – HyperNeutrino Jun 11 '17 at 20:55
2
\$\begingroup\$

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!

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.