aze (v3)

Revision 3 of this benchmark created on


Description

aze

Setup

var RotateLeft = function (lValue, iShiftBits) {
	
    return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
	
};
	
function AddUnsigned(lX, lY) {
	
    var lX8 = lX & 0x80000000;
	
    var lY8 = lY & 0x80000000;
	
    var lX4 = lX & 0x40000000;
	
    var lY4 = lY & 0x40000000;
	
    var lResult = (lX & 0x3fffffff) + (lY & 0x3fffffff);
	
    if (lX4 & lY4) {
	
        return lResult ^ 0x80000000 ^ lX8 ^ lY8;
	
    }
	
    if (lX4 | lY4) {
	
        return lResult ^ (lResult & 0x40000000 ? 0xc0000000 : 0x40000000) ^ lX8 ^ lY8;
	
    }
	
    else {
	
        return lResult ^ lX8 ^ lY8;
	
    }
	
}
	
var F = function (x, y, z) { return (x & y) | (~x & z); };
	
var G = function (x, y, z) { return (x & z) | (y & ~z); };
	
var H = function (x, y, z) { return x ^ y ^ z; };
	
var I = function (x, y, z) { return y ^ (x | ~z); };
	
function FF(a, b, c, d, x, s, ac) {
	
    a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
	
    return AddUnsigned(RotateLeft(a, s), b);
	
}
	
function GG(a, b, c, d, x, s, ac) {
	
    a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
	
    return AddUnsigned(RotateLeft(a, s), b);
	
}
	
function HH(a, b, c, d, x, s, ac) {
	
    a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
	
    return AddUnsigned(RotateLeft(a, s), b);
	
}
	
function II(a, b, c, d, x, s, ac) {
	
    a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
	
    return AddUnsigned(RotateLeft(a, s), b);
	
}
	
function ConvertToWordArray(str) {
	
    var lWordCount;
	
    var lMessageLength = str.length;
	
    var lNumberOfWordsTemp1 = lMessageLength + 8;
	
    var lNumberOfWordsTemp2 = (lNumberOfWordsTemp1 - (lNumberOfWordsTemp1 % 64)) / 64;
	
    var lNumberOfWords = (lNumberOfWordsTemp2 + 1) * 16;
	
    var lWordArray = Array(lNumberOfWords - 1);
	
    var lBytePosition = 0;
	
    var lByteCount = 0;
	
    while (lByteCount < lMessageLength) {
	
        lWordCount = (lByteCount - (lByteCount % 4)) / 4;
	
        lBytePosition = (lByteCount % 4) * 8;
	
        lWordArray[lWordCount] = lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition);
	
        lByteCount++;
	
    }
	
    lWordCount = (lByteCount - (lByteCount % 4)) / 4;
	
    lBytePosition = (lByteCount % 4) * 8;
	
    lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
	
    lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
	
    lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
	
    return lWordArray;
	
}
	
function WordToHex(lValue) {
	
    var WordToHexValue = '';
	
    var WordToHexValueTemp = '';
	
    var lByte;
	
    var lCount;
	
    for (lCount = 0; lCount <= 3; lCount++) {
	
        lByte = (lValue >>> (lCount * 8)) & 255;
	
        WordToHexValueTemp = '0' + lByte.toString(16);
	
        WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);
	
    }
	
    return WordToHexValue;
	
}
	
function Utf8Encode(str) {
	
    str = (str + '').replace(/\r\n/g, '\n');
	
    var utftext = '';
	
    for (var n = 0; n < str.length; n++) {
	
        var c = str.charCodeAt(n);
	
        if (c < 128) {
	
            utftext += String.fromCharCode(c);
	
        }
	
        else if (c > 127 && c < 2048) {
	
            utftext += String.fromCharCode((c >> 6) | 192);
	
            utftext += String.fromCharCode((c & 63) | 128);
	
        }
	
        else {
	
            utftext += String.fromCharCode((c >> 12) | 224);
	
            utftext += String.fromCharCode(((c >> 6) & 63) | 128);
	
            utftext += String.fromCharCode((c & 63) | 128);
	
        }
	
    }
	
    return utftext;
	
}
	
var S11 = 7;
	
var S12 = 12;
	
var S13 = 17;
	
var S14 = 22;
	
var S21 = 5;
	
var S22 = 9;
	
var S23 = 14;
	
var S24 = 20;
	
var S31 = 4;
	
var S32 = 11;
	
var S33 = 16;
	
var S34 = 23;
	
var S41 = 6;
	
var S42 = 10;
	
var S43 = 15;
	
var S44 = 21;
	
function md5_2(str) {
	
    var k;
	
    var AA;
	
    var BB;
	
    var CC;
	
    var DD;
	
    str = Utf8Encode(str);
	
    var x = ConvertToWordArray(str);
	
    var a = 0x67452301;
	
    var b = 0xefcdab89;
	
    var c = 0x98badcfe;
	
    var d = 0x10325476;
	
    for (k = 0; k < x.length; k += 16) {
	
        AA = a;
	
        BB = b;
	
        CC = c;
	
        DD = d;
	
        a = FF(a, b, c, d, x[k + 0], S11, 0xd76aa478);
	
        d = FF(d, a, b, c, x[k + 1], S12, 0xe8c7b756);
	
        c = FF(c, d, a, b, x[k + 2], S13, 0x242070db);
	
        b = FF(b, c, d, a, x[k + 3], S14, 0xc1bdceee);
	
        a = FF(a, b, c, d, x[k + 4], S11, 0xf57c0faf);
	
        d = FF(d, a, b, c, x[k + 5], S12, 0x4787c62a);
	
        c = FF(c, d, a, b, x[k + 6], S13, 0xa8304613);
	
        b = FF(b, c, d, a, x[k + 7], S14, 0xfd469501);
	
        a = FF(a, b, c, d, x[k + 8], S11, 0x698098d8);
	
        d = FF(d, a, b, c, x[k + 9], S12, 0x8b44f7af);
	
        c = FF(c, d, a, b, x[k + 10], S13, 0xffff5bb1);
	
        b = FF(b, c, d, a, x[k + 11], S14, 0x895cd7be);
	
        a = FF(a, b, c, d, x[k + 12], S11, 0x6b901122);
	
        d = FF(d, a, b, c, x[k + 13], S12, 0xfd987193);
	
        c = FF(c, d, a, b, x[k + 14], S13, 0xa679438e);
	
        b = FF(b, c, d, a, x[k + 15], S14, 0x49b40821);
	
        a = GG(a, b, c, d, x[k + 1], S21, 0xf61e2562);
	
        d = GG(d, a, b, c, x[k + 6], S22, 0xc040b340);
	
        c = GG(c, d, a, b, x[k + 11], S23, 0x265e5a51);
	
        b = GG(b, c, d, a, x[k + 0], S24, 0xe9b6c7aa);
	
        a = GG(a, b, c, d, x[k + 5], S21, 0xd62f105d);
	
        d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
	
        c = GG(c, d, a, b, x[k + 15], S23, 0xd8a1e681);
	
        b = GG(b, c, d, a, x[k + 4], S24, 0xe7d3fbc8);
	
        a = GG(a, b, c, d, x[k + 9], S21, 0x21e1cde6);
	
        d = GG(d, a, b, c, x[k + 14], S22, 0xc33707d6);
	
        c = GG(c, d, a, b, x[k + 3], S23, 0xf4d50d87);
	
        b = GG(b, c, d, a, x[k + 8], S24, 0x455a14ed);
	
        a = GG(a, b, c, d, x[k + 13], S21, 0xa9e3e905);
	
        d = GG(d, a, b, c, x[k + 2], S22, 0xfcefa3f8);
	
        c = GG(c, d, a, b, x[k + 7], S23, 0x676f02d9);
	
        b = GG(b, c, d, a, x[k + 12], S24, 0x8d2a4c8a);
	
        a = HH(a, b, c, d, x[k + 5], S31, 0xfffa3942);
	
        d = HH(d, a, b, c, x[k + 8], S32, 0x8771f681);
	
        c = HH(c, d, a, b, x[k + 11], S33, 0x6d9d6122);
	
        b = HH(b, c, d, a, x[k + 14], S34, 0xfde5380c);
	
        a = HH(a, b, c, d, x[k + 1], S31, 0xa4beea44);
	
        d = HH(d, a, b, c, x[k + 4], S32, 0x4bdecfa9);
	
        c = HH(c, d, a, b, x[k + 7], S33, 0xf6bb4b60);
	
        b = HH(b, c, d, a, x[k + 10], S34, 0xbebfbc70);
	
        a = HH(a, b, c, d, x[k + 13], S31, 0x289b7ec6);
	
        d = HH(d, a, b, c, x[k + 0], S32, 0xeaa127fa);
	
        c = HH(c, d, a, b, x[k + 3], S33, 0xd4ef3085);
	
        b = HH(b, c, d, a, x[k + 6], S34, 0x4881d05);
	
        a = HH(a, b, c, d, x[k + 9], S31, 0xd9d4d039);
	
        d = HH(d, a, b, c, x[k + 12], S32, 0xe6db99e5);
	
        c = HH(c, d, a, b, x[k + 15], S33, 0x1fa27cf8);
	
        b = HH(b, c, d, a, x[k + 2], S34, 0xc4ac5665);
	
        a = II(a, b, c, d, x[k + 0], S41, 0xf4292244);
	
        d = II(d, a, b, c, x[k + 7], S42, 0x432aff97);
	
        c = II(c, d, a, b, x[k + 14], S43, 0xab9423a7);
	
        b = II(b, c, d, a, x[k + 5], S44, 0xfc93a039);
	
        a = II(a, b, c, d, x[k + 12], S41, 0x655b59c3);
	
        d = II(d, a, b, c, x[k + 3], S42, 0x8f0ccc92);
	
        c = II(c, d, a, b, x[k + 10], S43, 0xffeff47d);
	
        b = II(b, c, d, a, x[k + 1], S44, 0x85845dd1);
	
        a = II(a, b, c, d, x[k + 8], S41, 0x6fa87e4f);
	
        d = II(d, a, b, c, x[k + 15], S42, 0xfe2ce6e0);
	
        c = II(c, d, a, b, x[k + 6], S43, 0xa3014314);
	
        b = II(b, c, d, a, x[k + 13], S44, 0x4e0811a1);
	
        a = II(a, b, c, d, x[k + 4], S41, 0xf7537e82);
	
        d = II(d, a, b, c, x[k + 11], S42, 0xbd3af235);
	
        c = II(c, d, a, b, x[k + 2], S43, 0x2ad7d2bb);
	
        b = II(b, c, d, a, x[k + 9], S44, 0xeb86d391);
	
        a = AddUnsigned(a, AA);
	
        b = AddUnsigned(b, BB);
	
        c = AddUnsigned(c, CC);
	
        d = AddUnsigned(d, DD);
	
    }
	
    return (WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d)).toLowerCase();
	
};



var MD5 = function (string) {

   function RotateLeft(lValue, iShiftBits) {
           return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
   }

   function AddUnsigned(lX,lY) {
           var lX4,lY4,lX8,lY8,lResult;
           lX8 = (lX & 0x80000000);
           lY8 = (lY & 0x80000000);
           lX4 = (lX & 0x40000000);
           lY4 = (lY & 0x40000000);
           lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
           if (lX4 & lY4) {
                   return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
           }
           if (lX4 | lY4) {
                   if (lResult & 0x40000000) {
                           return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
                   } else {
                           return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
                   }
           } else {
                   return (lResult ^ lX8 ^ lY8);
           }
   }

   function F(x,y,z) { return (x & y) | ((~x) & z); }
   function G(x,y,z) { return (x & z) | (y & (~z)); }
   function H(x,y,z) { return (x ^ y ^ z); }
   function I(x,y,z) { return (y ^ (x | (~z))); }

   function FF(a,b,c,d,x,s,ac) {
           a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
           return AddUnsigned(RotateLeft(a, s), b);
   };

   function GG(a,b,c,d,x,s,ac) {
           a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
           return AddUnsigned(RotateLeft(a, s), b);
   };

   function HH(a,b,c,d,x,s,ac) {
           a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
           return AddUnsigned(RotateLeft(a, s), b);
   };

   function II(a,b,c,d,x,s,ac) {
           a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
           return AddUnsigned(RotateLeft(a, s), b);
   };

   function ConvertToWordArray(string) {
           var lWordCount;
           var lMessageLength = string.length;
           var lNumberOfWords_temp1=lMessageLength + 8;
           var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
           var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
           var lWordArray=Array(lNumberOfWords-1);
           var lBytePosition = 0;
           var lByteCount = 0;
           while ( lByteCount < lMessageLength ) {
                   lWordCount = (lByteCount-(lByteCount % 4))/4;
                   lBytePosition = (lByteCount % 4)*8;
                   lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
                   lByteCount++;
           }
           lWordCount = (lByteCount-(lByteCount % 4))/4;
           lBytePosition = (lByteCount % 4)*8;
           lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
           lWordArray[lNumberOfWords-2] = lMessageLength<<3;
           lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
           return lWordArray;
   };

   function WordToHex(lValue) {
           var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
           for (lCount = 0;lCount<=3;lCount++) {
                   lByte = (lValue>>>(lCount*8)) & 255;
                   WordToHexValue_temp = "0" + lByte.toString(16);
                   WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
           }
           return WordToHexValue;
   };

   function Utf8Encode(string) {
           string = string.replace(/\r\n/g,"\n");
           var utftext = "";

           for (var n = 0; n < string.length; n++) {

                   var c = string.charCodeAt(n);

                   if (c < 128) {
                           utftext += String.fromCharCode(c);
                   }
                   else if((c > 127) && (c < 2048)) {
                           utftext += String.fromCharCode((c >> 6) | 192);
                           utftext += String.fromCharCode((c & 63) | 128);
                   }
                   else {
                           utftext += String.fromCharCode((c >> 12) | 224);
                           utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                           utftext += String.fromCharCode((c & 63) | 128);
                   }

           }

           return utftext;
   };

   var x=Array();
   var k,AA,BB,CC,DD,a,b,c,d;
   var S11=7, S12=12, S13=17, S14=22;
   var S21=5, S22=9 , S23=14, S24=20;
   var S31=4, S32=11, S33=16, S34=23;
   var S41=6, S42=10, S43=15, S44=21;

   string = Utf8Encode(string);

   x = ConvertToWordArray(string);

   a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;

   for (k=0;k<x.length;k+=16) {
           AA=a; BB=b; CC=c; DD=d;
           a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
           d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
           c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
           b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
           a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
           d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
           c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
           b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
           a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
           d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
           c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
           b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
           a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
           d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
           c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
           b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
           a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
           d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
           c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
           b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
           a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
           d=GG(d,a,b,c,x[k+10],S22,0x2441453);
           c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
           b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
           a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
           d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
           c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
           b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
           a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
           d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
           c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
           b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
           a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
           d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
           c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
           b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
           a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
           d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
           c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
           b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
           a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
           d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
           c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
           b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
           a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
           d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
           c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
           b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
           a=II(a,b,c,d,x[k+0], S41,0xF4292244);
           d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
           c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
           b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
           a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
           d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
           c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
           b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
           a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
           d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
           c=II(c,d,a,b,x[k+6], S43,0xA3014314);
           b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
           a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
           d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
           c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
           b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
           a=AddUnsigned(a,AA);
           b=AddUnsigned(b,BB);
           c=AddUnsigned(c,CC);
           d=AddUnsigned(d,DD);
   		}

   	var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);

   	return temp.toLowerCase();
}


  /**
   * Add integers, wrapping at 2^32.
   * This uses 16-bit operations internally to work around bugs in interpreters.
   *
   * @param {number} x First integer
   * @param {number} y Second integer
   * @returns {number} Sum
   */
  function safeAdd(x, y) {
    var lsw = (x & 0xffff) + (y & 0xffff)
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
    return (msw << 16) | (lsw & 0xffff)
  }

  /**
   * Bitwise rotate a 32-bit number to the left.
   *
   * @param {number} num 32-bit number
   * @param {number} cnt Rotation count
   * @returns {number} Rotated number
   */
  function bitRotateLeft(num, cnt) {
    return (num << cnt) | (num >>> (32 - cnt))
  }

  /**
   * Basic operation the algorithm uses.
   *
   * @param {number} q q
   * @param {number} a a
   * @param {number} b b
   * @param {number} x x
   * @param {number} s s
   * @param {number} t t
   * @returns {number} Result
   */
  function md5cmn(q, a, b, x, s, t) {
    return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b)
  }
  /**
   * Basic operation the algorithm uses.
   *
   * @param {number} a a
   * @param {number} b b
   * @param {number} c c
   * @param {number} d d
   * @param {number} x x
   * @param {number} s s
   * @param {number} t t
   * @returns {number} Result
   */
  function md5ff(a, b, c, d, x, s, t) {
    return md5cmn((b & c) | (~b & d), a, b, x, s, t)
  }
  /**
   * Basic operation the algorithm uses.
   *
   * @param {number} a a
   * @param {number} b b
   * @param {number} c c
   * @param {number} d d
   * @param {number} x x
   * @param {number} s s
   * @param {number} t t
   * @returns {number} Result
   */
  function md5gg(a, b, c, d, x, s, t) {
    return md5cmn((b & d) | (c & ~d), a, b, x, s, t)
  }
  /**
   * Basic operation the algorithm uses.
   *
   * @param {number} a a
   * @param {number} b b
   * @param {number} c c
   * @param {number} d d
   * @param {number} x x
   * @param {number} s s
   * @param {number} t t
   * @returns {number} Result
   */
  function md5hh(a, b, c, d, x, s, t) {
    return md5cmn(b ^ c ^ d, a, b, x, s, t)
  }
  /**
   * Basic operation the algorithm uses.
   *
   * @param {number} a a
   * @param {number} b b
   * @param {number} c c
   * @param {number} d d
   * @param {number} x x
   * @param {number} s s
   * @param {number} t t
   * @returns {number} Result
   */
  function md5ii(a, b, c, d, x, s, t) {
    return md5cmn(c ^ (b | ~d), a, b, x, s, t)
  }

  /**
   * Calculate the MD5 of an array of little-endian words, and a bit length.
   *
   * @param {Array} x Array of little-endian words
   * @param {number} len Bit length
   * @returns {Array<number>} MD5 Array
   */
  function binlMD5(x, len) {
    /* append padding */
    x[len >> 5] |= 0x80 << len % 32
    x[(((len + 64) >>> 9) << 4) + 14] = len

    var i
    var olda
    var oldb
    var oldc
    var oldd
    var a = 1732584193
    var b = -271733879
    var c = -1732584194
    var d = 271733878

    for (i = 0; i < x.length; i += 16) {
      olda = a
      oldb = b
      oldc = c
      oldd = d

      a = md5ff(a, b, c, d, x[i], 7, -680876936)
      d = md5ff(d, a, b, c, x[i + 1], 12, -389564586)
      c = md5ff(c, d, a, b, x[i + 2], 17, 606105819)
      b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330)
      a = md5ff(a, b, c, d, x[i + 4], 7, -176418897)
      d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426)
      c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341)
      b = md5ff(b, c, d, a, x[i + 7], 22, -45705983)
      a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416)
      d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417)
      c = md5ff(c, d, a, b, x[i + 10], 17, -42063)
      b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162)
      a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682)
      d = md5ff(d, a, b, c, x[i + 13], 12, -40341101)
      c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290)
      b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329)

      a = md5gg(a, b, c, d, x[i + 1], 5, -165796510)
      d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632)
      c = md5gg(c, d, a, b, x[i + 11], 14, 643717713)
      b = md5gg(b, c, d, a, x[i], 20, -373897302)
      a = md5gg(a, b, c, d, x[i + 5], 5, -701558691)
      d = md5gg(d, a, b, c, x[i + 10], 9, 38016083)
      c = md5gg(c, d, a, b, x[i + 15], 14, -660478335)
      b = md5gg(b, c, d, a, x[i + 4], 20, -405537848)
      a = md5gg(a, b, c, d, x[i + 9], 5, 568446438)
      d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690)
      c = md5gg(c, d, a, b, x[i + 3], 14, -187363961)
      b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501)
      a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467)
      d = md5gg(d, a, b, c, x[i + 2], 9, -51403784)
      c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473)
      b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734)

      a = md5hh(a, b, c, d, x[i + 5], 4, -378558)
      d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463)
      c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562)
      b = md5hh(b, c, d, a, x[i + 14], 23, -35309556)
      a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060)
      d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353)
      c = md5hh(c, d, a, b, x[i + 7], 16, -155497632)
      b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640)
      a = md5hh(a, b, c, d, x[i + 13], 4, 681279174)
      d = md5hh(d, a, b, c, x[i], 11, -358537222)
      c = md5hh(c, d, a, b, x[i + 3], 16, -722521979)
      b = md5hh(b, c, d, a, x[i + 6], 23, 76029189)
      a = md5hh(a, b, c, d, x[i + 9], 4, -640364487)
      d = md5hh(d, a, b, c, x[i + 12], 11, -421815835)
      c = md5hh(c, d, a, b, x[i + 15], 16, 530742520)
      b = md5hh(b, c, d, a, x[i + 2], 23, -995338651)

      a = md5ii(a, b, c, d, x[i], 6, -198630844)
      d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415)
      c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905)
      b = md5ii(b, c, d, a, x[i + 5], 21, -57434055)
      a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571)
      d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606)
      c = md5ii(c, d, a, b, x[i + 10], 15, -1051523)
      b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799)
      a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359)
      d = md5ii(d, a, b, c, x[i + 15], 10, -30611744)
      c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380)
      b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649)
      a = md5ii(a, b, c, d, x[i + 4], 6, -145523070)
      d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379)
      c = md5ii(c, d, a, b, x[i + 2], 15, 718787259)
      b = md5ii(b, c, d, a, x[i + 9], 21, -343485551)

      a = safeAdd(a, olda)
      b = safeAdd(b, oldb)
      c = safeAdd(c, oldc)
      d = safeAdd(d, oldd)
    }
    return [a, b, c, d]
  }

  /**
   * Convert an array of little-endian words to a string
   *
   * @param {Array<number>} input MD5 Array
   * @returns {string} MD5 string
   */
  function binl2rstr(input) {
    var i
    var output = ''
    var length32 = input.length * 32
    for (i = 0; i < length32; i += 8) {
      output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff)
    }
    return output
  }

  /**
   * Convert a raw string to an array of little-endian words
   * Characters >255 have their high-byte silently ignored.
   *
   * @param {string} input Raw input string
   * @returns {Array<number>} Array of little-endian words
   */
  function rstr2binl(input) {
    var i
    var output = []
    output[(input.length >> 2) - 1] = undefined
    for (i = 0; i < output.length; i += 1) {
      output[i] = 0
    }
    var length8 = input.length * 8
    for (i = 0; i < length8; i += 8) {
      output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32
    }
    return output
  }

  /**
   * Calculate the MD5 of a raw string
   *
   * @param {string} s Input string
   * @returns {string} Raw MD5 string
   */
  function rstrMD5(s) {
    return binl2rstr(binlMD5(rstr2binl(s), s.length * 8))
  }

  /**
   * Calculates the HMAC-MD5 of a key and some data (raw strings)
   *
   * @param {string} key HMAC key
   * @param {string} data Raw input string
   * @returns {string} Raw MD5 string
   */
  function rstrHMACMD5(key, data) {
    var i
    var bkey = rstr2binl(key)
    var ipad = []
    var opad = []
    var hash
    ipad[15] = opad[15] = undefined
    if (bkey.length > 16) {
      bkey = binlMD5(bkey, key.length * 8)
    }
    for (i = 0; i < 16; i += 1) {
      ipad[i] = bkey[i] ^ 0x36363636
      opad[i] = bkey[i] ^ 0x5c5c5c5c
    }
    hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8)
    return binl2rstr(binlMD5(opad.concat(hash), 512 + 128))
  }

  /**
   * Convert a raw string to a hex string
   *
   * @param {string} input Raw input string
   * @returns {string} Hex encoded string
   */
  function rstr2hex(input) {
    var hexTab = '0123456789abcdef'
    var output = ''
    var x
    var i
    for (i = 0; i < input.length; i += 1) {
      x = input.charCodeAt(i)
      output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f)
    }
    return output
  }

  /**
   * Encode a string as UTF-8
   *
   * @param {string} input Input string
   * @returns {string} UTF8 string
   */
  function str2rstrUTF8(input) {
    return unescape(encodeURIComponent(input))
  }

  /**
   * Encodes input string as raw MD5 string
   *
   * @param {string} s Input string
   * @returns {string} Raw MD5 string
   */
  function rawMD5(s) {
    return rstrMD5(str2rstrUTF8(s))
  }
  /**
   * Encodes input string as Hex encoded string
   *
   * @param {string} s Input string
   * @returns {string} Hex encoded string
   */
  function hexMD5(s) {
    return rstr2hex(rawMD5(s))
  }
  /**
   * Calculates the raw HMAC-MD5 for the given key and data
   *
   * @param {string} k HMAC key
   * @param {string} d Input string
   * @returns {string} Raw MD5 string
   */
  function rawHMACMD5(k, d) {
    return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d))
  }
  /**
   * Calculates the Hex encoded HMAC-MD5 for the given key and data
   *
   * @param {string} k HMAC key
   * @param {string} d Input string
   * @returns {string} Raw MD5 string
   */
  function hexHMACMD5(k, d) {
    return rstr2hex(rawHMACMD5(k, d))
  }

  /**
   * Calculates MD5 value for a given string.
   * If a key is provided, calculates the HMAC-MD5 value.
   * Returns a Hex encoded string unless the raw argument is given.
   *
   * @param {string} string Input string
   * @param {string} [key] HMAC key
   * @param {boolean} [raw] Raw output switch
   * @returns {string} MD5 output
   */
  function md5(string, key, raw) {
    if (!key) {
      if (!raw) {
        return hexMD5(string)
      }
      return rawMD5(string)
    }
    if (!raw) {
      return hexHMACMD5(key, string)
    }
    return rawHMACMD5(key, string)
  }





  function safeAdd(x, y) {
    var lsw = (x & 0xffff) + (y & 0xffff)
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
    return (msw << 16) | (lsw & 0xffff)
  }

  function bitRotateLeft(num, cnt) {
    return (num << cnt) | (num >>> (32 - cnt))
  }

  function md5cmn(q, a, b, x, s, t) {
    return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b)
  }

  function md5ff(a, b, c, d, x, s, t) {
    return md5cmn((b & c) | (~b & d), a, b, x, s, t)
  }

  function md5gg(a, b, c, d, x, s, t) {
    return md5cmn((b & d) | (c & ~d), a, b, x, s, t)
  }

  function md5hh(a, b, c, d, x, s, t) {
    return md5cmn(b ^ c ^ d, a, b, x, s, t)
  }

  function md5ii(a, b, c, d, x, s, t) {
    return md5cmn(c ^ (b | ~d), a, b, x, s, t)
  }

  function binlMD5(x, len) {
    /* append padding */
    x[len >> 5] |= 0x80 << len % 32
    x[(((len + 64) >>> 9) << 4) + 14] = len

    var i
    var olda
    var oldb
    var oldc
    var oldd
    var a = 1732584193
    var b = -271733879
    var c = -1732584194
    var d = 271733878

    for (i = 0; i < x.length; i += 16) {
      olda = a
      oldb = b
      oldc = c
      oldd = d

      a = md5ff(a, b, c, d, x[i], 7, -680876936)
      d = md5ff(d, a, b, c, x[i + 1], 12, -389564586)
      c = md5ff(c, d, a, b, x[i + 2], 17, 606105819)
      b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330)
      a = md5ff(a, b, c, d, x[i + 4], 7, -176418897)
      d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426)
      c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341)
      b = md5ff(b, c, d, a, x[i + 7], 22, -45705983)
      a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416)
      d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417)
      c = md5ff(c, d, a, b, x[i + 10], 17, -42063)
      b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162)
      a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682)
      d = md5ff(d, a, b, c, x[i + 13], 12, -40341101)
      c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290)
      b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329)

      a = md5gg(a, b, c, d, x[i + 1], 5, -165796510)
      d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632)
      c = md5gg(c, d, a, b, x[i + 11], 14, 643717713)
      b = md5gg(b, c, d, a, x[i], 20, -373897302)
      a = md5gg(a, b, c, d, x[i + 5], 5, -701558691)
      d = md5gg(d, a, b, c, x[i + 10], 9, 38016083)
      c = md5gg(c, d, a, b, x[i + 15], 14, -660478335)
      b = md5gg(b, c, d, a, x[i + 4], 20, -405537848)
      a = md5gg(a, b, c, d, x[i + 9], 5, 568446438)
      d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690)
      c = md5gg(c, d, a, b, x[i + 3], 14, -187363961)
      b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501)
      a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467)
      d = md5gg(d, a, b, c, x[i + 2], 9, -51403784)
      c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473)
      b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734)

      a = md5hh(a, b, c, d, x[i + 5], 4, -378558)
      d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463)
      c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562)
      b = md5hh(b, c, d, a, x[i + 14], 23, -35309556)
      a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060)
      d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353)
      c = md5hh(c, d, a, b, x[i + 7], 16, -155497632)
      b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640)
      a = md5hh(a, b, c, d, x[i + 13], 4, 681279174)
      d = md5hh(d, a, b, c, x[i], 11, -358537222)
      c = md5hh(c, d, a, b, x[i + 3], 16, -722521979)
      b = md5hh(b, c, d, a, x[i + 6], 23, 76029189)
      a = md5hh(a, b, c, d, x[i + 9], 4, -640364487)
      d = md5hh(d, a, b, c, x[i + 12], 11, -421815835)
      c = md5hh(c, d, a, b, x[i + 15], 16, 530742520)
      b = md5hh(b, c, d, a, x[i + 2], 23, -995338651)

      a = md5ii(a, b, c, d, x[i], 6, -198630844)
      d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415)
      c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905)
      b = md5ii(b, c, d, a, x[i + 5], 21, -57434055)
      a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571)
      d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606)
      c = md5ii(c, d, a, b, x[i + 10], 15, -1051523)
      b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799)
      a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359)
      d = md5ii(d, a, b, c, x[i + 15], 10, -30611744)
      c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380)
      b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649)
      a = md5ii(a, b, c, d, x[i + 4], 6, -145523070)
      d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379)
      c = md5ii(c, d, a, b, x[i + 2], 15, 718787259)
      b = md5ii(b, c, d, a, x[i + 9], 21, -343485551)

      a = safeAdd(a, olda)
      b = safeAdd(b, oldb)
      c = safeAdd(c, oldc)
      d = safeAdd(d, oldd)
    }
    return [a, b, c, d]
  }

  function binl2rstr(input) {
    var i
    var output = ''
    var length32 = input.length * 32
    for (i = 0; i < length32; i += 8) {
      output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff)
    }
    return output
  }

  function rstr2binl(input) {
    var i
    var output = []
    output[(input.length >> 2) - 1] = undefined
    for (i = 0; i < output.length; i += 1) {
      output[i] = 0
    }
    var length8 = input.length * 8
    for (i = 0; i < length8; i += 8) {
      output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32
    }
    return output
  }

  function rstrMD5(s) {
    return binl2rstr(binlMD5(rstr2binl(s), s.length * 8))
  }

  function str2rstrUTF8(input) {
    return unescape(encodeURIComponent(input))
  }

  function rawMD5(s) {
    return rstrMD5(str2rstrUTF8(s))
  }

  function md5(string) {
    return rawMD5(string)
  }
  
  
  
  
  function md5_gpt(str) {
  const rotateLeft = (lValue, iShiftBits) => (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));

  const addUnsigned = (lX, lY) => {
    let lX4, lY4, lX8, lY8, lResult;
    lX8 = (lX & 0x80000000) | 0x80000000;
    lY8 = (lY & 0x80000000) | 0x80000000;
    lX4 = (lX & 0x40000000) | 0x40000000;
    lY4 = (lY & 0x40000000) | 0x40000000;
    lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
    if (lX4 & lY4) {
      return lResult ^ 0x80000000 ^ lX8 ^ lY8;
    }
    if (lX4 | lY4) {
      if (lResult & 0x40000000) {
        return lResult ^ 0xC0000000 ^ lX8 ^ lY8;
      } else {
        return lResult ^ 0x40000000 ^ lX8 ^ lY8;
      }
    } else {
      return lResult ^ lX8 ^ lY8;
    }
  };

  const F = (x, y, z) => (x & y) | (~x & z);
  const G = (x, y, z) => (x & z) | (y & ~z);
  const H = (x, y, z) => x ^ y ^ z;
  const I = (x, y, z) => y ^ (x | ~z);

  const convertToWordArray = (str) => {
    let lWordCount;
    const lMessageLength = str.length;
    const lNumberOfWordsTemp1 = lMessageLength + 8;
    const lNumberOfWordsTemp2 = (lNumberOfWordsTemp1 - (lNumberOfWordsTemp1 % 64)) / 64;
    const lNumberOfWords = (lNumberOfWordsTemp2 + 1) * 16;
    const lWordArray = new Array(lNumberOfWords - 1);
    let lBytePosition = 0;
    let lByteCount = 0;
    while (lByteCount < lMessageLength) {
      lWordCount = (lByteCount - (lByteCount % 4)) / 4;
      lBytePosition = (lByteCount % 4) * 8;
      lWordArray[lWordCount] |= str.charCodeAt(lByteCount) << lBytePosition;
      lByteCount++;
    }
    lWordCount = (lByteCount - (lByteCount % 4)) / 4;
    lBytePosition = (lByteCount % 4) * 8;
    lWordArray[lWordCount] |= 0x80 << lBytePosition;
    lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
    lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
    return lWordArray;
  };

  const wordToHex = (lValue) => {
    let wordToHexValue = "",
      wordToHexValueTemp = "",
      lByte,
      lCount;
    for (lCount = 0; lCount <= 3; lCount++) {
      lByte = (lValue >>> (lCount * 8)) & 255;
      wordToHexValueTemp = "0" + lByte.toString(16);
      wordToHexValue += wordToHexValueTemp.substr(wordToHexValueTemp.length - 2, 2);
    }
    return wordToHexValue;
  };

  let x = [],
    k, AA, BB, CC, DD, a, b, c, d, S11 = 7,
    S12 = 12,
    S13 = 17,
    S14 = 22,
    S21 = 5,
    S22 = 9,
    S23 = 14,
    S24 = 20,
    S31 = 4,
    S32 = 11,
    S33 = 16,
    S34 = 23,
    S41 = 6,
    S42 = 10,
    S43 = 15,
    S44 = 21;

  str = unescape(encodeURIComponent(str));
  x = convertToWordArray(str);
  a = 0x67452301;
  b = 0xEFCDAB89;
  c = 0x98BADCFE;
  d = 0x10325476;

  for (k = 0; k < x.length; k += 16) {
    AA = a;
    BB = b;
    CC = c;
    DD = d;
    a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
    d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
    c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
    b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
    a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
    d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
    c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
    b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
    a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
    d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
    c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
    b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
    a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
    d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
    c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
    b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
    a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
    d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
    c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
    b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
    a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
    d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
    c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
    b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
    a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
    d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
    c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
    b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
    a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
    d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
    c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
    b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
    a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
    d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
    c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
    b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
    a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
    d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
    c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
    b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
    a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
    d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
    c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
    b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
    a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
    d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
    c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
    b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
    a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
    d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
    c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
    b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
    a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
    d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
    c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
    b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
    a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
    d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
    c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
    b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
    a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
    d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
    c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
    b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
    a = addUnsigned(a, AA);
    b = addUnsigned(b, BB);
    c = addUnsigned(c, CC);
    d = addUnsigned(d, DD);
  }

  const tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
  return tempValue.toLowerCase();
}





const HEX_CHARS = "0123456789abcdef"
const EXTRA = [128, 32768, 8388608, -2147483648]
const BUFFER = new ArrayBuffer(68)

class MyMd5 {
  constructor() {
    this.blocks = new Uint32Array(BUFFER)
    this.buffer8 = new Uint8Array(BUFFER)

    this.h0 = this.h1 = this.h2 = this.h3 = 0
    this.currentByte = this.bytes = this.hBytes = this.lastByteIndex = 0
    this.hashed = false
    this.first = true
  }

  md5(message) {
    let index = 0,
      blocks = this.blocks
    let buffer8 = this.buffer8

    while (index < message.length) {
      if (this.hashed) {
        this.hashed = false
        blocks[0] = blocks[16]
        this.blocks.fill(0, 1, 16)
      }

      let i = this.currentByte
      for (; index < message.length && i < 64; ++index) {
        let code = message.charCodeAt(index)
        if (code < 0x80) {
          buffer8[i++] = code
        } else if (code < 0x800) {
          buffer8[i++] = 0xc0 | (code >>> 6)
          buffer8[i++] = 0x80 | (code & 0x3f)
        } else if (code < 0xd800 || code >= 0xe000) {
          buffer8[i++] = 0xe0 | (code >>> 12)
          buffer8[i++] = 0x80 | ((code >>> 6) & 0x3f)
          buffer8[i++] = 0x80 | (code & 0x3f)
        } else {
          code =
            0x10000 +
            (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff))
          buffer8[i++] = 0xf0 | (code >>> 18)
          buffer8[i++] = 0x80 | ((code >>> 12) & 0x3f)
          buffer8[i++] = 0x80 | ((code >>> 6) & 0x3f)
          buffer8[i++] = 0x80 | (code & 0x3f)
        }
      }
      this.lastByteIndex = i
      this.bytes += i - this.currentByte
      if (i >= 64) {
        this.currentByte = i - 64
        this.md5Cycle()
        this.hashed = true
      } else {
        this.currentByte = i
      }
    }
    if (this.bytes > 4294967295) {
      this.hBytes += (this.bytes / 4294967296) << 0
      this.bytes = this.bytes % 4294967296
    }

    return this.hex()
  }

  md5Cycle() {
    let a, b, c, d, bc, da

    if (this.first) {
      a = this.blocks[0] - 680876937
      a = (((a << 7) | (a >>> 25)) - 271733879) << 0
      d = (-1732584194 ^ (a & 2004318071)) + this.blocks[1] - 117830708
      d = (((d << 12) | (d >>> 20)) + a) << 0
      c = (-271733879 ^ (d & (a ^ -271733879))) + this.blocks[2] - 1126478375
      c = (((c << 17) | (c >>> 15)) + d) << 0
      b = (a ^ (c & (d ^ a))) + this.blocks[3] - 1316259209
      b = (((b << 22) | (b >>> 10)) + c) << 0
    } else {
      a = this.h0
      b = this.h1
      c = this.h2
      d = this.h3
      a += (d ^ (b & (c ^ d))) + this.blocks[0] - 680876936
      a = (((a << 7) | (a >>> 25)) + b) << 0
      d += (c ^ (a & (b ^ c))) + this.blocks[1] - 389564586
      d = (((d << 12) | (d >>> 20)) + a) << 0
      c += (b ^ (d & (a ^ b))) + this.blocks[2] + 606105819
      c = (((c << 17) | (c >>> 15)) + d) << 0
      b += (a ^ (c & (d ^ a))) + this.blocks[3] - 1044525330
      b = (((b << 22) | (b >>> 10)) + c) << 0
    }

    a += (d ^ (b & (c ^ d))) + this.blocks[4] - 176418897
    a = (((a << 7) | (a >>> 25)) + b) << 0
    d += (c ^ (a & (b ^ c))) + this.blocks[5] + 1200080426
    d = (((d << 12) | (d >>> 20)) + a) << 0
    c += (b ^ (d & (a ^ b))) + this.blocks[6] - 1473231341
    c = (((c << 17) | (c >>> 15)) + d) << 0
    b += (a ^ (c & (d ^ a))) + this.blocks[7] - 45705983
    b = (((b << 22) | (b >>> 10)) + c) << 0
    a += (d ^ (b & (c ^ d))) + this.blocks[8] + 1770035416
    a = (((a << 7) | (a >>> 25)) + b) << 0
    d += (c ^ (a & (b ^ c))) + this.blocks[9] - 1958414417
    d = (((d << 12) | (d >>> 20)) + a) << 0
    c += (b ^ (d & (a ^ b))) + this.blocks[10] - 42063
    c = (((c << 17) | (c >>> 15)) + d) << 0
    b += (a ^ (c & (d ^ a))) + this.blocks[11] - 1990404162
    b = (((b << 22) | (b >>> 10)) + c) << 0
    a += (d ^ (b & (c ^ d))) + this.blocks[12] + 1804603682
    a = (((a << 7) | (a >>> 25)) + b) << 0
    d += (c ^ (a & (b ^ c))) + this.blocks[13] - 40341101
    d = (((d << 12) | (d >>> 20)) + a) << 0
    c += (b ^ (d & (a ^ b))) + this.blocks[14] - 1502002290
    c = (((c << 17) | (c >>> 15)) + d) << 0
    b += (a ^ (c & (d ^ a))) + this.blocks[15] + 1236535329
    b = (((b << 22) | (b >>> 10)) + c) << 0
    a += (c ^ (d & (b ^ c))) + this.blocks[1] - 165796510
    a = (((a << 5) | (a >>> 27)) + b) << 0
    d += (b ^ (c & (a ^ b))) + this.blocks[6] - 1069501632
    d = (((d << 9) | (d >>> 23)) + a) << 0
    c += (a ^ (b & (d ^ a))) + this.blocks[11] + 643717713
    c = (((c << 14) | (c >>> 18)) + d) << 0
    b += (d ^ (a & (c ^ d))) + this.blocks[0] - 373897302
    b = (((b << 20) | (b >>> 12)) + c) << 0
    a += (c ^ (d & (b ^ c))) + this.blocks[5] - 701558691
    a = (((a << 5) | (a >>> 27)) + b) << 0
    d += (b ^ (c & (a ^ b))) + this.blocks[10] + 38016083
    d = (((d << 9) | (d >>> 23)) + a) << 0
    c += (a ^ (b & (d ^ a))) + this.blocks[15] - 660478335
    c = (((c << 14) | (c >>> 18)) + d) << 0
    b += (d ^ (a & (c ^ d))) + this.blocks[4] - 405537848
    b = (((b << 20) | (b >>> 12)) + c) << 0
    a += (c ^ (d & (b ^ c))) + this.blocks[9] + 568446438
    a = (((a << 5) | (a >>> 27)) + b) << 0
    d += (b ^ (c & (a ^ b))) + this.blocks[14] - 1019803690
    d = (((d << 9) | (d >>> 23)) + a) << 0
    c += (a ^ (b & (d ^ a))) + this.blocks[3] - 187363961
    c = (((c << 14) | (c >>> 18)) + d) << 0
    b += (d ^ (a & (c ^ d))) + this.blocks[8] + 1163531501
    b = (((b << 20) | (b >>> 12)) + c) << 0
    a += (c ^ (d & (b ^ c))) + this.blocks[13] - 1444681467
    a = (((a << 5) | (a >>> 27)) + b) << 0
    d += (b ^ (c & (a ^ b))) + this.blocks[2] - 51403784
    d = (((d << 9) | (d >>> 23)) + a) << 0
    c += (a ^ (b & (d ^ a))) + this.blocks[7] + 1735328473
    c = (((c << 14) | (c >>> 18)) + d) << 0
    b += (d ^ (a & (c ^ d))) + this.blocks[12] - 1926607734
    b = (((b << 20) | (b >>> 12)) + c) << 0
    bc = b ^ c
    a += (bc ^ d) + this.blocks[5] - 378558
    a = (((a << 4) | (a >>> 28)) + b) << 0
    d += (bc ^ a) + this.blocks[8] - 2022574463
    d = (((d << 11) | (d >>> 21)) + a) << 0
    da = d ^ a
    c += (da ^ b) + this.blocks[11] + 1839030562
    c = (((c << 16) | (c >>> 16)) + d) << 0
    b += (da ^ c) + this.blocks[14] - 35309556
    b = (((b << 23) | (b >>> 9)) + c) << 0
    bc = b ^ c
    a += (bc ^ d) + this.blocks[1] - 1530992060
    a = (((a << 4) | (a >>> 28)) + b) << 0
    d += (bc ^ a) + this.blocks[4] + 1272893353
    d = (((d << 11) | (d >>> 21)) + a) << 0
    da = d ^ a
    c += (da ^ b) + this.blocks[7] - 155497632
    c = (((c << 16) | (c >>> 16)) + d) << 0
    b += (da ^ c) + this.blocks[10] - 1094730640
    b = (((b << 23) | (b >>> 9)) + c) << 0
    bc = b ^ c
    a += (bc ^ d) + this.blocks[13] + 681279174
    a = (((a << 4) | (a >>> 28)) + b) << 0
    d += (bc ^ a) + this.blocks[0] - 358537222
    d = (((d << 11) | (d >>> 21)) + a) << 0
    da = d ^ a
    c += (da ^ b) + this.blocks[3] - 722521979
    c = (((c << 16) | (c >>> 16)) + d) << 0
    b += (da ^ c) + this.blocks[6] + 76029189
    b = (((b << 23) | (b >>> 9)) + c) << 0
    bc = b ^ c
    a += (bc ^ d) + this.blocks[9] - 640364487
    a = (((a << 4) | (a >>> 28)) + b) << 0
    d += (bc ^ a) + this.blocks[12] - 421815835
    d = (((d << 11) | (d >>> 21)) + a) << 0
    da = d ^ a
    c += (da ^ b) + this.blocks[15] + 530742520
    c = (((c << 16) | (c >>> 16)) + d) << 0
    b += (da ^ c) + this.blocks[2] - 995338651
    b = (((b << 23) | (b >>> 9)) + c) << 0
    a += (c ^ (b | ~d)) + this.blocks[0] - 198630844
    a = (((a << 6) | (a >>> 26)) + b) << 0
    d += (b ^ (a | ~c)) + this.blocks[7] + 1126891415
    d = (((d << 10) | (d >>> 22)) + a) << 0
    c += (a ^ (d | ~b)) + this.blocks[14] - 1416354905
    c = (((c << 15) | (c >>> 17)) + d) << 0
    b += (d ^ (c | ~a)) + this.blocks[5] - 57434055
    b = (((b << 21) | (b >>> 11)) + c) << 0
    a += (c ^ (b | ~d)) + this.blocks[12] + 1700485571
    a = (((a << 6) | (a >>> 26)) + b) << 0
    d += (b ^ (a | ~c)) + this.blocks[3] - 1894986606
    d = (((d << 10) | (d >>> 22)) + a) << 0
    c += (a ^ (d | ~b)) + this.blocks[10] - 1051523
    c = (((c << 15) | (c >>> 17)) + d) << 0
    b += (d ^ (c | ~a)) + this.blocks[1] - 2054922799
    b = (((b << 21) | (b >>> 11)) + c) << 0
    a += (c ^ (b | ~d)) + this.blocks[8] + 1873313359
    a = (((a << 6) | (a >>> 26)) + b) << 0
    d += (b ^ (a | ~c)) + this.blocks[15] - 30611744
    d = (((d << 10) | (d >>> 22)) + a) << 0
    c += (a ^ (d | ~b)) + this.blocks[6] - 1560198380
    c = (((c << 15) | (c >>> 17)) + d) << 0
    b += (d ^ (c | ~a)) + this.blocks[13] + 1309151649
    b = (((b << 21) | (b >>> 11)) + c) << 0
    a += (c ^ (b | ~d)) + this.blocks[4] - 145523070
    a = (((a << 6) | (a >>> 26)) + b) << 0
    d += (b ^ (a | ~c)) + this.blocks[11] - 1120210379
    d = (((d << 10) | (d >>> 22)) + a) << 0
    c += (a ^ (d | ~b)) + this.blocks[2] + 718787259
    c = (((c << 15) | (c >>> 17)) + d) << 0
    b += (d ^ (c | ~a)) + this.blocks[9] - 343485551
    b = (((b << 21) | (b >>> 11)) + c) << 0

    if (this.first) {
      this.h0 = (a + 1732584193) << 0
      this.h1 = (b - 271733879) << 0
      this.h2 = (c - 1732584194) << 0
      this.h3 = (d + 271733878) << 0
      this.first = false
    } else {
      this.h0 = (this.h0 + a) << 0
      this.h1 = (this.h1 + b) << 0
      this.h2 = (this.h2 + c) << 0
      this.h3 = (this.h3 + d) << 0
    }
  }

  hex() {
    this.blocks[this.lastByteIndex >>> 2] |= EXTRA[this.lastByteIndex & 3]
    if (this.lastByteIndex >= 56) {
      this.blocks[0] = this.blocks[16]
      this.blocks.fill(0, 1, 16)
    }
    this.blocks[14] = this.bytes << 3
    this.blocks[15] = (this.hBytes << 3) | (this.bytes >>> 29)
    this.md5Cycle()

    return (
      HEX_CHARS[(this.h0 >>> 4) & 0x0f] +
      HEX_CHARS[this.h0 & 0x0f] +
      HEX_CHARS[(this.h0 >>> 12) & 0x0f] +
      HEX_CHARS[(this.h0 >>> 8) & 0x0f] +
      HEX_CHARS[(this.h0 >>> 20) & 0x0f] +
      HEX_CHARS[(this.h0 >>> 16) & 0x0f] +
      HEX_CHARS[(this.h0 >>> 28) & 0x0f] +
      HEX_CHARS[(this.h0 >>> 24) & 0x0f] +
      HEX_CHARS[(this.h1 >>> 4) & 0x0f] +
      HEX_CHARS[this.h1 & 0x0f] +
      HEX_CHARS[(this.h1 >>> 12) & 0x0f] +
      HEX_CHARS[(this.h1 >>> 8) & 0x0f] +
      HEX_CHARS[(this.h1 >>> 20) & 0x0f] +
      HEX_CHARS[(this.h1 >>> 16) & 0x0f] +
      HEX_CHARS[(this.h1 >>> 28) & 0x0f] +
      HEX_CHARS[(this.h1 >>> 24) & 0x0f] +
      HEX_CHARS[(this.h2 >>> 4) & 0x0f] +
      HEX_CHARS[this.h2 & 0x0f] +
      HEX_CHARS[(this.h2 >>> 12) & 0x0f] +
      HEX_CHARS[(this.h2 >>> 8) & 0x0f] +
      HEX_CHARS[(this.h2 >>> 20) & 0x0f] +
      HEX_CHARS[(this.h2 >>> 16) & 0x0f] +
      HEX_CHARS[(this.h2 >>> 28) & 0x0f] +
      HEX_CHARS[(this.h2 >>> 24) & 0x0f] +
      HEX_CHARS[(this.h3 >>> 4) & 0x0f] +
      HEX_CHARS[this.h3 & 0x0f] +
      HEX_CHARS[(this.h3 >>> 12) & 0x0f] +
      HEX_CHARS[(this.h3 >>> 8) & 0x0f] +
      HEX_CHARS[(this.h3 >>> 20) & 0x0f] +
      HEX_CHARS[(this.h3 >>> 16) & 0x0f] +
      HEX_CHARS[(this.h3 >>> 28) & 0x0f] +
      HEX_CHARS[(this.h3 >>> 24) & 0x0f]
    )
  }
}

console.log(new MyMd5().md5("hello"))

Test runner

Ready to run.

Testing in
TestOps/sec
md5_2
md5_2('こんにちは')
ready
MD5
MD5('こんにちは')
ready
md5
md5('こんにちは')
ready
md5_gpt
md5_gpt('こんにちは')
ready
md5 fast
new MyMd5().md5('こんにちは')
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.