/ *
* A JavaScript Implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, As Defined IN RFC 1321.
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
* Other Contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed Under The BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
* /
/ *
* Configurable variables. You may need to Tweak these to be compatible with
* The Server-Side, But The Defaults Work In Most Cases.
* /
Var hexcase = 0; / * HEX OUTPUT FORMAT. 0 - LowerCase; 1 - Uppercase * /
VAR B64PAD = ""; / * base-64 pad character. "=" = "for strict rfc company"
Var Chrsz = 8; / * bits per input character. 8 - ascii; 16 - unicode * /
/ *
* THESE is the functions you'll Usually Want to CALL
* They take string arguments and return Either Hex Or Base-64 Encode Strings
* /
Function HEX_MD5 (S) {RETURN BINL2HEX (Core_MD5 (STR2binl (s), S.Length * Chrsz);}
Function B64_MD5 (S) {RETURN BINL2B64 (Core_MD5 (Str2binl (s), S.LENGTH * ChRSZ);}
Function STR_MD5 (S) {RETURN BINL2STR (Core_MD5 (Str2binl (s), S.Length * Chrsz);}
Function HEX_HMAC_MD5 (Key, DATA) {Return BINL2HEX (Core_HMAC_MD5 (KEY, DATA));}
Function B64_HMAC_MD5 (Key, DATA) {RETURN BINL2B64 (Core_HMAC_MD5 (KEY, DATA));}
Function str_hmac_md5 (key, data) {return binl2str (Core_HMAC_MD5 (KEY, DATA));}
/ *
* Perform A Simple Self-test to see reason the vm is working
* /
Function MD5_VM_TEST ()
{
RETURN HEX_MD5 ("ABC") == "900150983cd24fb0d6963f7d28e17f72";
}
/ *
* Calculate the md5 of an array of little-endian words, and a bit length
* /
Function core_md5 (x, len)
{
/ * append padding * /
X [Len >> 5] | = 0x80 << ((len)% 32); X [((((Len 64) >>> 9) << 4) 14] = LEN;
VAR a = 1732584193;
VAR b = -271733879;
VAR C = -1732584194;
VAR D = 271733878;
For (var i = 0; i { VAR OLDA = a; VAR oldb = b; VAR OLDC = C; VAR Oldd = D; A = MD5_FF (A, B, C, D, X [i 0], 7, -680876936); D = MD5_FF (D, A, B, C, X [i 1], 12, -389564586); C = MD5_FF (C, D, A, B, X [i 2], 17, 606105819); B = MD5_FF (B, C, D, A, X [i 3], 22, -1044525330); A = MD5_FF (A, B, C, D, X [i 4], 7, -176418897); D = MD5_FF (D, A, B, C, X [i 5], 12, 1200080426); C = MD5_FF (C, D, A, B, X [i 6], 17, -1473231341); B = MD5_FF (B, C, D, A, X [i 7], 22, -45705983); A = MD5_FF (A, B, C, D, X [i 8], 7, 1770035416); D = MD5_FF (D, A, B, C, X [i 9], 12, -1958414417); C = MD5_FF (C, D, A, B, X [i 10], 17, -42063); B = MD5_FF (B, C, D, A, X [i 11], 22, -1990404162); A = MD5_FF (A, B, C, D, X [i 12], 7, 1804603682); D = MD5_FF (D, A, B, C, X [i 13], 12, -40341101); C = MD5_FF (C, D, A, B, X [i 14], 17, -1502002290); B = MD5_FF (B, C, D, A, X [i 15], 22, 1236535329); A = MD5_GG (A, B, C, D, X [i 1], 5, -165796510); D = MD5_GG (D, A, B, C, X [i 6], 9, -1069501632); C = MD5_GG (C, D, A, B, X [i 11], 14, 643717713); B = MD5_GG (B, C, D, A, X [i 0], 20, -373897302); A = MD5_GG (A, B, C, D, X [i 5], 5, -701558691); D = MD5_GG (D, A, B, C, X [i 10], 9, 38016083); C = MD5_GG (C, D, A, B, X [i 15], 14, -660478335); B = MD5_GG (B, C, D, A, X [i 4], 20, -405537848); A = MD5_GG (A, B, C, D, X [i 9], 5, 568446438); D = MD5_GG (D, A, B, C, X [i 14], 9, -1019803690); C = MD5_GG (C, D, A, B, X [i 3], 14, -187363961); B = MD5_GG (B, C, D, A, X [i 8], 20, 1163531501); A = MD5_GG (A, B, C, D, X [i 13], 5, -1444681467); D = MD5_GG (D, A, B, C, X [i 2], 9, -51403784); C = MD5_GG (C, D, A, B, X [i 7], 14, 1735328473); B = MD5_GG (B, C, D, A, X [i 12], 20, -1926607734); A = MD5_HH (A, B, C, D, X [i 5], 4, -378558); D = MD5_HH (D, A, B, C, X [i 8], 11, -2022574463); C = MD5_HH (C, D, A, B, X [i 11], 16, 1839030562); B = MD5_HH (B, C, D, A, X [i 14], 23, -35309556); A = MD5_HH (A, B, C, D, X [i 1], 4, -1530992060); D = MD5_HH (D, A, B, C, X [i 4], 11, 1272893353); C = MD5_HH (C, D, A, B, X [i 7], 16, -155497632); B = MD5_HH (B, C, D, A, X [i 10], 23, -1094730640); A = MD5_HH (A, B, C, D, X [i 13], 4, 681279174); D = MD5_HH (D, A, B, C, X [i 0], 11, -358537222); C = MD5_HH (C, D, A, B, X [i 3], 16, -722521979); B = MD5_HH (B, C, D, A, X [i 6], 23, 76029189); A = MD5_HH (A, B, C, D, X [i 9], 4, -640364487); D = MD5_HH (D, A, B, C, X [i 12], 11, -421815835); C = MD5_HH (C, D, A, B, X [i 15], 16, 530742520); B = MD5_HH (B, C, D, A, X [i 2], 23, -995338651); A = MD5_II (A, B, C, D, X [i 0], 6, -198630844); D = MD5_II (D, A, B, C, X [i 7], 10, 1126891415); C = MD5_II (C, D, A, B, X [i 14], 15, -1416354905); B = MD5_II (B, C, D, A, X [i 5], 21, -57434055); A = MD5_II (A, B, C, D, X [i 12], 6, 1700485571); D = MD5_II (D, A, B, C, X [i 3], 10, -1894986606); C = MD5_II (C, D, A, B, X [i 10], 15, -1051523); B = MD5_II (B, C, D, A, X [i 1], 21, -2054922799); A = MD5_II (A, B, C, D, X [i 8], 6, 1873313359); D = MD5_II (D, A, B, C, X [i 15], 10, -30611744); C = MD5_II (C, D, A, B, X [i 6], 15, -1560198380); B = MD5_II (B, C, D, A, X [i 13], 21, 1309151649); A = MD5_II (A, B, C, D, X [i 4], 6, -145523070); D = MD5_II (D, A, B, C, X [i 11], 10, -1120210379); C = MD5_II (C, D, A, B, X [i 2], 15, 718787259); B = MD5_II (B, C, D, A, X [i 9], 21, -343485551); A = SAFE_ADD (A, OLDA); B = SAFE_ADD (B, OLDB); C = SAFE_ADD (C, OLDC); D = SAFE_ADD (D, OLDD); } Return Array (A, B, C, D); } / * * THESE Functions Implement The Four Basic Operations The Algorithm Uses. * / Function MD5_CMN (Q, A, B, X, S, T) { RETURN SAFE_ADD (Bit_ROL (Safe_ADD (Safe_ADD (A, Q), SAFE_ADD (X, T)), S), B); } Function MD5_FF (A, B, C, D, X, S, T) { RETURN MD5_CMN ((B & C) | ((~ b) & d), A, B, X, S, T); } Function MD5_GG (A, B, C, D, X, S, T) { RETURN MD5_CMN ((B & D) | (C & (~ D)), A, B, X, S, T); } Function MD5_HH (A, B, C, D, X, S, T) { RETURN MD5_CMN (B ^ C ^ D, A, B, X, S, T); } Function MD5_II (A, B, C, D, X, S, T) { RETURN MD5_CMN (C ^ (B | (~ D)), A, B, X, S, T); } / * * Calculate The HMAC-MD5, OF A KEY AND SOME DATA * / Function core_hmac_md5 (key, data) { VAR BKEY = Str2binl (key); IF (BKey.length> 16) BKEY = CORE_MD5 (BKEY, Key.Length * Chrsz); Var ipad = array (16), opad = array (16); FOR (var i = 0; i <16; i ) { ipad [i] = bkey [i] ^ 0x36363636; Opad [i] = bkey [i] ^ 0x5c5c5c5c; } Var Hash = CORE_MD5 (iPad.concat), 512 Data.Length * Chrsz); Return Core_MD5 (Opad.concat (Hash), 512 128); } / * * Add Integers, Wraping AT 2 ^ 32. This uses 16-bit Operations INTERNALLY * To Work Around Bugs in Some JS Interpreters. * / Function Safe_Add (x, y) { VAR LSW = (X & 0xFFFF) (Y & 0xFFF); VAR MSW = (x >> 16) (Y >> 16) (LSW >> 16); Return (MSW << 16) | (LSW & 0xFFF); } / * * Bitwise Rotate a 32-bit number to the left. * / Function Bit_rol (Num, CNT) { Return (NUM << CNT) | (NUM >>> (32 - CNT)); } / * * Convert a string to an array of little-endian words * If Chrsz is ASCII, Characters> 255 Have their hi-byte silently ignored. * / Function str2binl (STR) { VAR bin = array (); Var mask = (1 << chrsz) - 1; For (var i = 0; i BIN [I >> 5] | = (Str.Charcodeat (I / Chrsz) & Mask << (i% 32); Return bin; } / * * Convert An Array of Little-Endian Words to A String * / Function BINL2STR (BIN) { Var str = "" Var mask = (1 << chrsz) - 1; For (var i = 0; i Str = string.fromcharcode ((BIN [I >> 5] >>> (I% 32)) & Mask Return Str; } / * * Convert An Array of Little-Endian Words to a hex string. * / Function BINL2HEX (BINARRAY) { Var hex_tab = hexcase? "0123456789abcdef": "0123456789Abcdef"; Var str = "" For (var i = 0; i { Str = HEX_TAB.CHARAT ((BinArray [i >> 2] >> ((i% 4) * 8 4) & 0xF) HEX_TAB.CHARAT ((BinArray [I >> 2] >> ((i% 4) * 8)) & 0xF); Return Str; } / * * Convert An Array of Little-Endian Words To A Base-64 String * / Function BINL2B64 (BINARRAY) { Var Tab = "Abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789 /"; Var str = "" For (var i = 0; i { VAR Triplet = ((Binarray [i >> 2] >> 8 * (I% 4)) & 0xff) << 16) ((Binarray [i 1 >> 2] >> 8 * ((i 1)% 4) & 0xff) << 8) ((Binarray [i 2 >> 2] >> 8 * ((i 2)% 4) & 0xff); FOR (VAR J = 0; J <4; J ) { IF (i * 8 j * 6> binarray.Length * 32) STR = B64Pad; Else Str = Tab.Charat (Triplet >> 6 * (3-J)) & 0x3f); } } Return Str; }