/*
	MD5 Message-Digest Algorithm
	IETF RFC 1321
	JavaScript implementation by tavis@email.com
*/


function md5(msg)
{
	var i, j, t;
	var b = msg.length * 8;

	msg += String.fromCharCode(0x80);

	while (msg.length % 64 != 56)
	{
		msg += String.fromCharCode(0);
	}

	for (i = 0; i < 8; i++)
	{
		msg += String.fromCharCode(b & 0xFF);
		b >>= 8;
	}

	var A = 0x67452301;
	var B = 0xefcdab89;
	var C = 0x98badcfe;
	var D = 0x10325476;

	var K = new Array(0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
	                  1,  6, 11,  0,  5, 10, 15,  4,  9, 14,  3,  8, 13,  2,  7, 12,
	                  5,  8, 11, 14,  1,  4,  7, 10, 13,  0,  3,  6,  9, 12, 15,  2,
	                  0,  7, 14,  5, 12,  3, 10,  1,  8, 15,  6, 13,  4, 11,  2,  9);

	var S = new Array(7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
	                  5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,
	                  4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
	                  6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21);

	var T = new Array(64);

	for (i = 0; i < 64; i++)
	{
		T[i] = Math.floor(Math.abs(Math.sin(i + 1) * Math.pow(2, 32)));
	}

	var X = new Array(16);

	for (i = 0; i < msg.length;)
	{
		var AA = A;
		var BB = B;
		var CC = C;
		var DD = D;

		for (j = 0; j < 16; j++)
		{
			X[j] = msg.charCodeAt(i++);
			X[j] |= msg.charCodeAt(i++) << 8;
			X[j] |= msg.charCodeAt(i++) << 16;
			X[j] |= msg.charCodeAt(i++) << 24;
		}

		for (t = 0; t < 64; t++)
		{
			var E = A + X[K[t]] + T[t];

			if      (t < 16) E += (B & C) | (~B & D);
			else if (t < 32) E += (B & D) | (C & ~D);
			else if (t < 48) E += B ^ C ^ D;
			else             E += C ^ (B | ~D);

			A = D;
			D = C;
			C = B;
			B += (E << S[t]) | (E >>> (32 - S[t]));
		}

		A += AA;
		B += BB;
		C += CC;
		D += DD;
	}

	return word2Hex(A) + word2Hex(B) + word2Hex(C) + word2Hex(D);
}

function word2Hex(W)
{
	return byte2Hex(W) + byte2Hex(W >> 8) + byte2Hex(W >> 16) + byte2Hex(W >> 24);
}

function byte2Hex(B)
{
	var digits = "0123456789abcdef";

	return digits.charAt((B >> 4) & 0xF) + digits.charAt(B & 0xF);
}
