2 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
3 * Digest Algorithm, as defined in RFC 1321.
4 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
5 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
6 * Distributed under the BSD License
7 * See http://pajhome.org.uk/crypt/md5 for more info.
11 * Configurable variables. You may need to tweak these to be compatible with
12 * the server-side, but the defaults work in most cases.
14 var hexcase
= 0; /* hex output format. 0 - lowercase; 1 - uppercase */
15 var b64pad
= ""; /* base-64 pad character. "=" for strict RFC compliance */
18 * These are the functions you'll usually want to call
19 * They take string arguments and return either hex or base-64 encoded strings
21 function hex_md5(s
) { return rstr2hex(rstr_md5(str2rstr_utf8(s
))); }
22 function b64_md5(s
) { return rstr2b64(rstr_md5(str2rstr_utf8(s
))); }
23 function any_md5(s
, e
) { return rstr2any(rstr_md5(str2rstr_utf8(s
)), e
); }
24 function hex_hmac_md5(k
, d
)
25 { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k
), str2rstr_utf8(d
))); }
26 function b64_hmac_md5(k
, d
)
27 { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k
), str2rstr_utf8(d
))); }
28 function any_hmac_md5(k
, d
, e
)
29 { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k
), str2rstr_utf8(d
)), e
); }
32 * Perform a simple self-test to see if the VM is working
34 function md5_vm_test()
36 return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72";
40 * Calculate the MD5 of a raw string
44 return binl2rstr(binl_md5(rstr2binl(s
), s
.length
* 8));
48 * Calculate the HMAC-MD5, of a key and some data (raw strings)
50 function rstr_hmac_md5(key
, data
)
52 var bkey
= rstr2binl(key
);
53 if(bkey
.length
> 16) bkey
= binl_md5(bkey
, key
.length
* 8);
55 var ipad
= Array(16), opad
= Array(16);
56 for(var i
= 0; i
< 16; i
++)
58 ipad
[i
] = bkey
[i
] ^ 0x36363636;
59 opad
[i
] = bkey
[i
] ^ 0x5C5C5C5C;
62 var hash
= binl_md5(ipad
.concat(rstr2binl(data
)), 512 + data
.length
* 8);
63 return binl2rstr(binl_md5(opad
.concat(hash
), 512 + 128));
67 * Convert a raw string to a hex string
69 function rstr2hex(input
)
71 try { hexcase
} catch(e
) { hexcase
=0; }
72 var hex_tab
= hexcase
? "0123456789ABCDEF" : "0123456789abcdef";
75 for(var i
= 0; i
< input
.length
; i
++)
77 x
= input
.charCodeAt(i
);
78 output
+= hex_tab
.charAt((x
>>> 4) & 0x0F)
79 + hex_tab
.charAt( x
& 0x0F);
85 * Convert a raw string to a base-64 string
87 function rstr2b64(input
)
89 try { b64pad
} catch(e
) { b64pad
=''; }
90 var tab
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
92 var len
= input
.length
;
93 for(var i
= 0; i
< len
; i
+= 3)
95 var triplet
= (input
.charCodeAt(i
) << 16)
96 | (i
+ 1 < len
? input
.charCodeAt(i
+1) << 8 : 0)
97 | (i
+ 2 < len
? input
.charCodeAt(i
+2) : 0);
98 for(var j
= 0; j
< 4; j
++)
100 if(i
* 8 + j
* 6 > input
.length
* 8) output
+= b64pad
;
101 else output
+= tab
.charAt((triplet
>>> 6*(3-j
)) & 0x3F);
108 * Convert a raw string to an arbitrary string encoding
110 function rstr2any(input
, encoding
)
112 var divisor
= encoding
.length
;
113 var i
, j
, q
, x
, quotient
;
115 /* Convert to an array of 16-bit big-endian values, forming the dividend */
116 var dividend
= Array(Math
.ceil(input
.length
/ 2));
117 for(i
= 0; i
< dividend
.length
; i
++)
119 dividend
[i
] = (input
.charCodeAt(i
* 2) << 8) | input
.charCodeAt(i
* 2 + 1);
123 * Repeatedly perform a long division. The binary array forms the dividend,
124 * the length of the encoding is the divisor. Once computed, the quotient
125 * forms the dividend for the next step. All remainders are stored for later
128 var full_length
= Math
.ceil(input
.length
* 8 /
129 (Math
.log(encoding
.length
) / Math
.log(2)));
130 var remainders
= Array(full_length
);
131 for(j
= 0; j
< full_length
; j
++)
135 for(i
= 0; i
< dividend
.length
; i
++)
137 x
= (x
<< 16) + dividend
[i
];
138 q
= Math
.floor(x
/ divisor
);
140 if(quotient
.length
> 0 || q
> 0)
141 quotient
[quotient
.length
] = q
;
147 /* Convert the remainders to the output string */
149 for(i
= remainders
.length
- 1; i
>= 0; i
--)
150 output
+= encoding
.charAt(remainders
[i
]);
156 * Encode a string as utf-8.
157 * For efficiency, this assumes the input is valid utf-16.
159 function str2rstr_utf8(input
)
165 while(++i
< input
.length
)
167 /* Decode utf-16 surrogate pairs */
168 x
= input
.charCodeAt(i
);
169 y
= i
+ 1 < input
.length
? input
.charCodeAt(i
+ 1) : 0;
170 if(0xD800 <= x
&& x
<= 0xDBFF && 0xDC00 <= y
&& y
<= 0xDFFF)
172 x
= 0x10000 + ((x
& 0x03FF) << 10) + (y
& 0x03FF);
176 /* Encode output as utf-8 */
178 output
+= String
.fromCharCode(x
);
180 output
+= String
.fromCharCode(0xC0 | ((x
>>> 6 ) & 0x1F),
183 output
+= String
.fromCharCode(0xE0 | ((x
>>> 12) & 0x0F),
184 0x80 | ((x
>>> 6 ) & 0x3F),
186 else if(x
<= 0x1FFFFF)
187 output
+= String
.fromCharCode(0xF0 | ((x
>>> 18) & 0x07),
188 0x80 | ((x
>>> 12) & 0x3F),
189 0x80 | ((x
>>> 6 ) & 0x3F),
196 * Encode a string as utf-16
198 function str2rstr_utf16le(input
)
201 for(var i
= 0; i
< input
.length
; i
++)
202 output
+= String
.fromCharCode( input
.charCodeAt(i
) & 0xFF,
203 (input
.charCodeAt(i
) >>> 8) & 0xFF);
207 function str2rstr_utf16be(input
)
210 for(var i
= 0; i
< input
.length
; i
++)
211 output
+= String
.fromCharCode((input
.charCodeAt(i
) >>> 8) & 0xFF,
212 input
.charCodeAt(i
) & 0xFF);
217 * Convert a raw string to an array of little-endian words
218 * Characters >255 have their high-byte silently ignored.
220 function rstr2binl(input
)
222 var output
= Array(input
.length
>> 2);
223 for(var i
= 0; i
< output
.length
; i
++)
225 for(var i
= 0; i
< input
.length
* 8; i
+= 8)
226 output
[i
>>5] |= (input
.charCodeAt(i
/ 8) & 0xFF) << (i
%32);
231 * Convert an array of little-endian words to a string
233 function binl2rstr(input
)
236 for(var i
= 0; i
< input
.length
* 32; i
+= 8)
237 output
+= String
.fromCharCode((input
[i
>>5] >>> (i
% 32)) & 0xFF);
242 * Calculate the MD5 of an array of little-endian words, and a bit length.
244 function binl_md5(x
, len
)
247 x
[len
>> 5] |= 0x80 << ((len
) % 32);
248 x
[(((len
+ 64) >>> 9) << 4) + 14] = len
;
255 for(var i
= 0; i
< x
.length
; i
+= 16)
262 a
= md5_ff(a
, b
, c
, d
, x
[i
+ 0], 7 , -680876936);
263 d
= md5_ff(d
, a
, b
, c
, x
[i
+ 1], 12, -389564586);
264 c
= md5_ff(c
, d
, a
, b
, x
[i
+ 2], 17, 606105819);
265 b
= md5_ff(b
, c
, d
, a
, x
[i
+ 3], 22, -1044525330);
266 a
= md5_ff(a
, b
, c
, d
, x
[i
+ 4], 7 , -176418897);
267 d
= md5_ff(d
, a
, b
, c
, x
[i
+ 5], 12, 1200080426);
268 c
= md5_ff(c
, d
, a
, b
, x
[i
+ 6], 17, -1473231341);
269 b
= md5_ff(b
, c
, d
, a
, x
[i
+ 7], 22, -45705983);
270 a
= md5_ff(a
, b
, c
, d
, x
[i
+ 8], 7 , 1770035416);
271 d
= md5_ff(d
, a
, b
, c
, x
[i
+ 9], 12, -1958414417);
272 c
= md5_ff(c
, d
, a
, b
, x
[i
+10], 17, -42063);
273 b
= md5_ff(b
, c
, d
, a
, x
[i
+11], 22, -1990404162);
274 a
= md5_ff(a
, b
, c
, d
, x
[i
+12], 7 , 1804603682);
275 d
= md5_ff(d
, a
, b
, c
, x
[i
+13], 12, -40341101);
276 c
= md5_ff(c
, d
, a
, b
, x
[i
+14], 17, -1502002290);
277 b
= md5_ff(b
, c
, d
, a
, x
[i
+15], 22, 1236535329);
279 a
= md5_gg(a
, b
, c
, d
, x
[i
+ 1], 5 , -165796510);
280 d
= md5_gg(d
, a
, b
, c
, x
[i
+ 6], 9 , -1069501632);
281 c
= md5_gg(c
, d
, a
, b
, x
[i
+11], 14, 643717713);
282 b
= md5_gg(b
, c
, d
, a
, x
[i
+ 0], 20, -373897302);
283 a
= md5_gg(a
, b
, c
, d
, x
[i
+ 5], 5 , -701558691);
284 d
= md5_gg(d
, a
, b
, c
, x
[i
+10], 9 , 38016083);
285 c
= md5_gg(c
, d
, a
, b
, x
[i
+15], 14, -660478335);
286 b
= md5_gg(b
, c
, d
, a
, x
[i
+ 4], 20, -405537848);
287 a
= md5_gg(a
, b
, c
, d
, x
[i
+ 9], 5 , 568446438);
288 d
= md5_gg(d
, a
, b
, c
, x
[i
+14], 9 , -1019803690);
289 c
= md5_gg(c
, d
, a
, b
, x
[i
+ 3], 14, -187363961);
290 b
= md5_gg(b
, c
, d
, a
, x
[i
+ 8], 20, 1163531501);
291 a
= md5_gg(a
, b
, c
, d
, x
[i
+13], 5 , -1444681467);
292 d
= md5_gg(d
, a
, b
, c
, x
[i
+ 2], 9 , -51403784);
293 c
= md5_gg(c
, d
, a
, b
, x
[i
+ 7], 14, 1735328473);
294 b
= md5_gg(b
, c
, d
, a
, x
[i
+12], 20, -1926607734);
296 a
= md5_hh(a
, b
, c
, d
, x
[i
+ 5], 4 , -378558);
297 d
= md5_hh(d
, a
, b
, c
, x
[i
+ 8], 11, -2022574463);
298 c
= md5_hh(c
, d
, a
, b
, x
[i
+11], 16, 1839030562);
299 b
= md5_hh(b
, c
, d
, a
, x
[i
+14], 23, -35309556);
300 a
= md5_hh(a
, b
, c
, d
, x
[i
+ 1], 4 , -1530992060);
301 d
= md5_hh(d
, a
, b
, c
, x
[i
+ 4], 11, 1272893353);
302 c
= md5_hh(c
, d
, a
, b
, x
[i
+ 7], 16, -155497632);
303 b
= md5_hh(b
, c
, d
, a
, x
[i
+10], 23, -1094730640);
304 a
= md5_hh(a
, b
, c
, d
, x
[i
+13], 4 , 681279174);
305 d
= md5_hh(d
, a
, b
, c
, x
[i
+ 0], 11, -358537222);
306 c
= md5_hh(c
, d
, a
, b
, x
[i
+ 3], 16, -722521979);
307 b
= md5_hh(b
, c
, d
, a
, x
[i
+ 6], 23, 76029189);
308 a
= md5_hh(a
, b
, c
, d
, x
[i
+ 9], 4 , -640364487);
309 d
= md5_hh(d
, a
, b
, c
, x
[i
+12], 11, -421815835);
310 c
= md5_hh(c
, d
, a
, b
, x
[i
+15], 16, 530742520);
311 b
= md5_hh(b
, c
, d
, a
, x
[i
+ 2], 23, -995338651);
313 a
= md5_ii(a
, b
, c
, d
, x
[i
+ 0], 6 , -198630844);
314 d
= md5_ii(d
, a
, b
, c
, x
[i
+ 7], 10, 1126891415);
315 c
= md5_ii(c
, d
, a
, b
, x
[i
+14], 15, -1416354905);
316 b
= md5_ii(b
, c
, d
, a
, x
[i
+ 5], 21, -57434055);
317 a
= md5_ii(a
, b
, c
, d
, x
[i
+12], 6 , 1700485571);
318 d
= md5_ii(d
, a
, b
, c
, x
[i
+ 3], 10, -1894986606);
319 c
= md5_ii(c
, d
, a
, b
, x
[i
+10], 15, -1051523);
320 b
= md5_ii(b
, c
, d
, a
, x
[i
+ 1], 21, -2054922799);
321 a
= md5_ii(a
, b
, c
, d
, x
[i
+ 8], 6 , 1873313359);
322 d
= md5_ii(d
, a
, b
, c
, x
[i
+15], 10, -30611744);
323 c
= md5_ii(c
, d
, a
, b
, x
[i
+ 6], 15, -1560198380);
324 b
= md5_ii(b
, c
, d
, a
, x
[i
+13], 21, 1309151649);
325 a
= md5_ii(a
, b
, c
, d
, x
[i
+ 4], 6 , -145523070);
326 d
= md5_ii(d
, a
, b
, c
, x
[i
+11], 10, -1120210379);
327 c
= md5_ii(c
, d
, a
, b
, x
[i
+ 2], 15, 718787259);
328 b
= md5_ii(b
, c
, d
, a
, x
[i
+ 9], 21, -343485551);
330 a
= safe_add(a
, olda
);
331 b
= safe_add(b
, oldb
);
332 c
= safe_add(c
, oldc
);
333 d
= safe_add(d
, oldd
);
335 return Array(a
, b
, c
, d
);
339 * These functions implement the four basic operations the algorithm uses.
341 function md5_cmn(q
, a
, b
, x
, s
, t
)
343 return safe_add(bit_rol(safe_add(safe_add(a
, q
), safe_add(x
, t
)), s
),b
);
345 function md5_ff(a
, b
, c
, d
, x
, s
, t
)
347 return md5_cmn((b
& c
) | ((~b
) & d
), a
, b
, x
, s
, t
);
349 function md5_gg(a
, b
, c
, d
, x
, s
, t
)
351 return md5_cmn((b
& d
) | (c
& (~d
)), a
, b
, x
, s
, t
);
353 function md5_hh(a
, b
, c
, d
, x
, s
, t
)
355 return md5_cmn(b
^ c
^ d
, a
, b
, x
, s
, t
);
357 function md5_ii(a
, b
, c
, d
, x
, s
, t
)
359 return md5_cmn(c
^ (b
| (~d
)), a
, b
, x
, s
, t
);
363 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
364 * to work around bugs in some JS interpreters.
366 function safe_add(x
, y
)
368 var lsw
= (x
& 0xFFFF) + (y
& 0xFFFF);
369 var msw
= (x
>> 16) + (y
>> 16) + (lsw
>> 16);
370 return (msw
<< 16) | (lsw
& 0xFFFF);
374 * Bitwise rotate a 32-bit number to the left.
376 function bit_rol(num
, cnt
)
378 return (num
<< cnt
) | (num
>>> (32 - cnt
));