Number.prototype.rotate = function(shiftBits)
{
    return (((this << shiftBits) % 4294967296) | (this >>> (32 - shiftBits)));
}

function getMd5(input) {
    var length = input.length * 8;
    input += String.fromCharCode(0x80);

    var padLen = (56 - (input.length % 64)) + 64 % 64;
    for (var i = 0; i < padLen; i++) { input += String.fromCharCode(0x00); } 

    for (i = 0; i < 8; i++) {
        input += String.fromCharCode((length / Math.pow(256, i)) & 0x000000FF);
    }

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

    var aa, bb, cc, dd, chunk, x;

    for (i = 0; chunk = input.substr(i * 64, 64); i++) {
        aa = a;
        bb = b;
        cc = c;
        dd = d;

        x = [];

        for (var ii = 0; ii < 16; ii++) {
            x[ii] = 0;
            for (var iii = 0; iii < 4; iii++) {
                x[ii] += chunk.charCodeAt((ii * 4) + iii) * Math.pow(256, iii);
            }
        }

        a=((b+(((a+((b&c)|((~b)&d))+x[0]+3614090360)%4294967296)).rotate(7))%4294967296);
        d=((a+(((d+((a&b)|((~a)&c))+x[1]+3905402710)%4294967296)).rotate(12))%4294967296);
        c=((d+(((c+((d&a)|((~d)&b))+x[2]+606105819)%4294967296)).rotate(17))%4294967296);
        b=((c+(((b+((c&d)|((~c)&a))+x[3]+3250441966)%4294967296)).rotate(22))%4294967296);
        a=((b+(((a+((b&c)|((~b)&d))+x[4]+4118548399)%4294967296)).rotate(7))%4294967296);
        d=((a+(((d+((a&b)|((~a)&c))+x[5]+1200080426)%4294967296)).rotate(12))%4294967296);
        c=((d+(((c+((d&a)|((~d)&b))+x[6]+2821735955)%4294967296)).rotate(17))%4294967296);
        b=((c+(((b+((c&d)|((~c)&a))+x[7]+4249261313)%4294967296)).rotate(22))%4294967296);
        a=((b+(((a+((b&c)|((~b)&d))+x[8]+1770035416)%4294967296)).rotate(7))%4294967296);
        d=((a+(((d+((a&b)|((~a)&c))+x[9]+2336552879)%4294967296)).rotate(12))%4294967296);
        c=((d+(((c+((d&a)|((~d)&b))+x[10]+4294925233)%4294967296)).rotate(17))%4294967296);
        b=((c+(((b+((c&d)|((~c)&a))+x[11]+2304563134)%4294967296)).rotate(22))%4294967296);
        a=((b+(((a+((b&c)|((~b)&d))+x[12]+1804603682)%4294967296)).rotate(7))%4294967296);
        d=((a+(((d+((a&b)|((~a)&c))+x[13]+4254626195)%4294967296)).rotate(12))%4294967296);
        c=((d+(((c+((d&a)|((~d)&b))+x[14]+2792965006)%4294967296)).rotate(17))%4294967296);
        b=((c+(((b+((c&d)|((~c)&a))+x[15]+1236535329)%4294967296)).rotate(22))%4294967296);
        a=((b+(((a+((b&d)|(c&(~d)))+x[1]+4129170786)%4294967296)).rotate(5))%4294967296);
        d=((a+(((d+((a&c)|(b&(~c)))+x[6]+3225465664)%4294967296)).rotate(9))%4294967296);
        c=((d+(((c+((d&b)|(a&(~b)))+x[11]+643717713)%4294967296)).rotate(14))%4294967296);
        b=((c+(((b+((c&a)|(d&(~a)))+x[0]+3921069994)%4294967296)).rotate(20))%4294967296);
        a=((b+(((a+((b&d)|(c&(~d)))+x[5]+3593408605)%4294967296)).rotate(5))%4294967296);
        d=((a+(((d+((a&c)|(b&(~c)))+x[10]+38016083)%4294967296)).rotate(9))%4294967296);
        c=((d+(((c+((d&b)|(a&(~b)))+x[15]+3634488961)%4294967296)).rotate(14))%4294967296);
        b=((c+(((b+((c&a)|(d&(~a)))+x[4]+3889429448)%4294967296)).rotate(20))%4294967296);
        a=((b+(((a+((b&d)|(c&(~d)))+x[9]+568446438)%4294967296)).rotate(5))%4294967296);
        d=((a+(((d+((a&c)|(b&(~c)))+x[14]+3275163606)%4294967296)).rotate(9))%4294967296);
        c=((d+(((c+((d&b)|(a&(~b)))+x[3]+4107603335)%4294967296)).rotate(14))%4294967296);
        b=((c+(((b+((c&a)|(d&(~a)))+x[8]+1163531501)%4294967296)).rotate(20))%4294967296);
        a=((b+(((a+((b&d)|(c&(~d)))+x[13]+2850285829)%4294967296)).rotate(5))%4294967296);
        d=((a+(((d+((a&c)|(b&(~c)))+x[2]+4243563512)%4294967296)).rotate(9))%4294967296);
        c=((d+(((c+((d&b)|(a&(~b)))+x[7]+1735328473)%4294967296)).rotate(14))%4294967296);
        b=((c+(((b+((c&a)|(d&(~a)))+x[12]+2368359562)%4294967296)).rotate(20))%4294967296);
        a=((b+(((a+(b^c^d)+x[5]+4294588738)%4294967296)).rotate(4))%4294967296);
        d=((a+(((d+(a^b^c)+x[8]+2272392833)%4294967296)).rotate(11))%4294967296);
        c=((d+(((c+(d^a^b)+x[11]+1839030562)%4294967296)).rotate(16))%4294967296);
        b=((c+(((b+(c^d^a)+x[14]+4259657740)%4294967296)).rotate(23))%4294967296);
        a=((b+(((a+(b^c^d)+x[1]+2763975236)%4294967296)).rotate(4))%4294967296);
        d=((a+(((d+(a^b^c)+x[4]+1272893353)%4294967296)).rotate(11))%4294967296);
        c=((d+(((c+(d^a^b)+x[7]+4139469664)%4294967296)).rotate(16))%4294967296);
        b=((c+(((b+(c^d^a)+x[10]+3200236656)%4294967296)).rotate(23))%4294967296);
        a=((b+(((a+(b^c^d)+x[13]+681279174)%4294967296)).rotate(4))%4294967296);
        d=((a+(((d+(a^b^c)+x[0]+3936430074)%4294967296)).rotate(11))%4294967296);
        c=((d+(((c+(d^a^b)+x[3]+3572445317)%4294967296)).rotate(16))%4294967296);
        b=((c+(((b+(c^d^a)+x[6]+76029189)%4294967296)).rotate(23))%4294967296);
        a=((b+(((a+(b^c^d)+x[9]+3654602809)%4294967296)).rotate(4))%4294967296);
        d=((a+(((d+(a^b^c)+x[12]+3873151461)%4294967296)).rotate(11))%4294967296);
        c=((d+(((c+(d^a^b)+x[15]+530742520)%4294967296)).rotate(16))%4294967296);
        b=((c+(((b+(c^d^a)+x[2]+3299628645)%4294967296)).rotate(23))%4294967296);
        a=((b+(((a+(c^(b|(~d)))+x[0]+4096336452)%4294967296)).rotate(6))%4294967296);
        d=((a+(((d+(b^(a|(~c)))+x[7]+1126891415)%4294967296)).rotate(10))%4294967296);
        c=((d+(((c+(a^(d|(~b)))+x[14]+2878612391)%4294967296)).rotate(15))%4294967296);
        b=((c+(((b+(d^(c|(~a)))+x[5]+4237533241)%4294967296)).rotate(21))%4294967296);
        a=((b+(((a+(c^(b|(~d)))+x[12]+1700485571)%4294967296)).rotate(6))%4294967296);
        d=((a+(((d+(b^(a|(~c)))+x[3]+2399980690)%4294967296)).rotate(10))%4294967296);
        c=((d+(((c+(a^(d|(~b)))+x[10]+4293915773)%4294967296)).rotate(15))%4294967296);
        b=((c+(((b+(d^(c|(~a)))+x[1]+2240044497)%4294967296)).rotate(21))%4294967296);
        a=((b+(((a+(c^(b|(~d)))+x[8]+1873313359)%4294967296)).rotate(6))%4294967296);
        d=((a+(((d+(b^(a|(~c)))+x[15]+4264355552)%4294967296)).rotate(10))%4294967296);
        c=((d+(((c+(a^(d|(~b)))+x[6]+2734768916)%4294967296)).rotate(15))%4294967296);
        b=((c+(((b+(d^(c|(~a)))+x[13]+1309151649)%4294967296)).rotate(21))%4294967296);
        a=((b+(((a+(c^(b|(~d)))+x[4]+4149444226)%4294967296)).rotate(6))%4294967296);
        d=((a+(((d+(b^(a|(~c)))+x[11]+3174756917)%4294967296)).rotate(10))%4294967296);
        c=((d+(((c+(a^(d|(~b)))+x[2]+718787259)%4294967296)).rotate(15))%4294967296);
        b=((c+(((b+(d^(c|(~a)))+x[9]+3951481745)%4294967296)).rotate(21))%4294967296);

        a=((a+aa)%4294967296);
        b=((b+bb)%4294967296);
        c=((c+cc)%4294967296);
        d=((d+dd)%4294967296);
    }

    var words = [a, b, c, d];
    
    var retStr = '';
    var byteStr = '';
    for (i = 0; i < 4; i++) {
        for (ii = 0; ii < 4; ii++) {
            byteStr = ((words[i] >>> (ii * 8)) & 0x000000FF).toString(16);
            retStr += ((byteStr.length == 1) ? '0' : '') + byteStr;
        }
    }
    return retStr;
}
