without logs
[deary.git] / javascripts / md5.js
blobf489f896c55793053913dc5b6a936360f84b43ea
1 /*
2  *  md5.jvs 1.0b 27/06/96
3  *
4  * Javascript implementation of the RSA Data Security, Inc. MD5
5  * Message-Digest Algorithm.
6  *
7  * Copyright (c) 1996 Henri Torgemane. All Rights Reserved.
8  *
9  * Permission to use, copy, modify, and distribute this software
10  * and its documentation for any purposes and without
11  * fee is hereby granted provided that this copyright notice
12  * appears in all copies. 
13  *
14  * Of course, this soft is provided "as is" without express or implied
15  * warranty of any kind.
17     This version contains some trivial reformatting modifications
18     by John Walker.
20  */
22 function array(n) {
23     for (i = 0; i < n; i++) {
24         this[i] = 0;
25     }
26     this.length = n;
29 /* Some basic logical functions had to be rewritten because of a bug in
30  * Javascript.. Just try to compute 0xffffffff >> 4 with it..
31  * Of course, these functions are slower than the original would be, but
32  * at least, they work!
33  */
35 function integer(n) {
36     return n % (0xffffffff + 1);
39 function shr(a, b) {
40     a = integer(a);
41     b = integer(b);
42     if (a - 0x80000000 >= 0) {
43         a = a % 0x80000000;
44         a >>= b;
45         a += 0x40000000 >> (b - 1);
46     } else {
47         a >>= b;
48     }
49     return a;
52 function shl1(a) {
53     a = a % 0x80000000;
54     if (a & 0x40000000 == 0x40000000) {
55         a -= 0x40000000;  
56         a *= 2;
57         a += 0x80000000;
58     } else {
59         a *= 2;
60     }
61     return a;
64 function shl(a, b) {
65     a = integer(a);
66     b = integer(b);
67     for (var i = 0; i < b; i++) {
68         a = shl1(a);
69     }
70     return a;
73 function and(a, b) {
74     a = integer(a);
75     b = integer(b);
76     var t1 = a - 0x80000000;
77     var t2 = b - 0x80000000;
78     if (t1 >= 0) {
79         if (t2 >= 0) {
80             return ((t1 & t2) + 0x80000000);
81         } else {
82             return (t1 & b);
83         }
84     } else {
85         if (t2 >= 0) {
86             return (a & t2);
87         } else {
88             return (a & b);  
89         }
90     }
93 function or(a, b) {
94     a = integer(a);
95     b = integer(b);
96     var t1 = a - 0x80000000;
97     var t2 = b - 0x80000000;
98     if (t1 >= 0) {
99         if (t2 >= 0) {
100             return ((t1 | t2) + 0x80000000);
101         } else {
102             return ((t1 | b) + 0x80000000);
103         }
104     } else {
105         if (t2 >= 0) {
106             return ((a | t2) + 0x80000000);
107         } else {
108             return (a | b);  
109         }
110     }
113 function xor(a, b) {
114     a = integer(a);
115     b = integer(b);
116     var t1 = a - 0x80000000;
117     var t2 = b - 0x80000000;
118     if (t1 >= 0) {
119         if (t2 >= 0) {
120             return (t1 ^ t2);
121         } else {
122             return ((t1 ^ b) + 0x80000000);
123         }
124     } else {
125         if (t2 >= 0) {
126             return ((a ^ t2) + 0x80000000);
127         } else {
128             return (a ^ b);  
129         }
130     }
133 function not(a) {
134     a = integer(a);
135     return 0xffffffff - a;
138 /* Here begin the real algorithm */
140 var state = new array(4); 
141 var count = new array(2);
142     count[0] = 0;
143     count[1] = 0;                     
144 var buffer = new array(64); 
145 var transformBuffer = new array(16); 
146 var digestBits = new array(16);
148 var S11 = 7;
149 var S12 = 12;
150 var S13 = 17;
151 var S14 = 22;
152 var S21 = 5;
153 var S22 = 9;
154 var S23 = 14;
155 var S24 = 20;
156 var S31 = 4;
157 var S32 = 11;
158 var S33 = 16;
159 var S34 = 23;
160 var S41 = 6;
161 var S42 = 10;
162 var S43 = 15;
163 var S44 = 21;
165 function F(x, y, z) {
166     return or(and(x, y), and(not(x), z));
169 function G(x, y, z) {
170     return or(and(x, z), and(y, not(z)));
173 function H(x, y, z) {
174     return xor(xor(x, y), z);
177 function I(x, y, z) {
178     return xor(y ,or(x , not(z)));
181 function rotateLeft(a, n) {
182     return or(shl(a, n), (shr(a, (32 - n))));
185 function FF(a, b, c, d, x, s, ac) {
186     a = a + F(b, c, d) + x + ac;
187     a = rotateLeft(a, s);
188     a = a + b;
189     return a;
192 function GG(a, b, c, d, x, s, ac) {
193     a = a + G(b, c, d) + x + ac;
194     a = rotateLeft(a, s);
195     a = a + b;
196     return a;
199 function HH(a, b, c, d, x, s, ac) {
200     a = a + H(b, c, d) + x + ac;
201     a = rotateLeft(a, s);
202     a = a + b;
203     return a;
206 function II(a, b, c, d, x, s, ac) {
207     a = a + I(b, c, d) + x + ac;
208     a = rotateLeft(a, s);
209     a = a + b;
210     return a;
213 function transform(buf, offset) { 
214     var a = 0, b = 0, c = 0, d = 0; 
215     var x = transformBuffer;
216     
217     a = state[0];
218     b = state[1];
219     c = state[2];
220     d = state[3];
221     
222     for (i = 0; i < 16; i++) {
223         x[i] = and(buf[i * 4 + offset], 0xFF);
224         for (j = 1; j < 4; j++) {
225             x[i] += shl(and(buf[i * 4 + j + offset] ,0xFF), j * 8);
226         }
227     }
229     /* Round 1 */
230     a = FF( a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
231     d = FF( d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
232     c = FF( c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
233     b = FF( b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
234     a = FF( a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
235     d = FF( d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
236     c = FF( c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
237     b = FF( b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
238     a = FF( a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
239     d = FF( d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
240     c = FF( c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
241     b = FF( b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
242     a = FF( a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
243     d = FF( d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
244     c = FF( c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
245     b = FF( b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
247     /* Round 2 */
248     a = GG( a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
249     d = GG( d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
250     c = GG( c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
251     b = GG( b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
252     a = GG( a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
253     d = GG( d, a, b, c, x[10], S22,  0x2441453); /* 22 */
254     c = GG( c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
255     b = GG( b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
256     a = GG( a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
257     d = GG( d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
258     c = GG( c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
259     b = GG( b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
260     a = GG( a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
261     d = GG( d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
262     c = GG( c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
263     b = GG( b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
265     /* Round 3 */
266     a = HH( a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
267     d = HH( d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
268     c = HH( c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
269     b = HH( b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
270     a = HH( a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
271     d = HH( d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
272     c = HH( c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
273     b = HH( b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
274     a = HH( a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
275     d = HH( d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
276     c = HH( c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
277     b = HH( b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
278     a = HH( a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
279     d = HH( d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
280     c = HH( c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
281     b = HH( b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
283     /* Round 4 */
284     a = II( a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
285     d = II( d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
286     c = II( c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
287     b = II( b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
288     a = II( a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
289     d = II( d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
290     c = II( c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
291     b = II( b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
292     a = II( a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
293     d = II( d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
294     c = II( c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
295     b = II( b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
296     a = II( a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
297     d = II( d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
298     c = II( c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
299     b = II( b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
301     state[0] += a;
302     state[1] += b;
303     state[2] += c;
304     state[3] += d;
308 function md5_init() {
309     count[0] = count[1] = 0;
310     state[0] = 0x67452301;
311     state[1] = 0xefcdab89;
312     state[2] = 0x98badcfe;
313     state[3] = 0x10325476;
314     for (i = 0; i < digestBits.length; i++) {
315         digestBits[i] = 0;
316     }
319 function md5_update(b) { 
320     var index, i;
321     
322     index = and(shr(count[0],3) , 0x3F);
323     if (count[0] < 0xFFFFFFFF - 7) {
324       count[0] += 8;
325     } else {
326       count[1]++;
327       count[0] -= 0xFFFFFFFF + 1;
328       count[0] += 8;
329     }
330     buffer[index] = and(b, 0xff);
331     if (index  >= 63) {
332         transform(buffer, 0);
333     }
336 function md5_finish() {
337     var bits = new array(8);
338     var padding; 
339     var i = 0, index = 0, padLen = 0;
341     for (i = 0; i < 4; i++) {
342         bits[i] = and(shr(count[0], (i * 8)), 0xFF);
343     }
344     for (i = 0; i < 4; i++) {
345         bits[i + 4] = and(shr(count[1], (i * 8)), 0xFF);
346     }
347     index = and(shr(count[0], 3), 0x3F);
348     padLen = (index < 56) ? (56 - index) : (120 - index);
349     padding = new array(64); 
350     padding[0] = 0x80;
351     for (i = 0; i < padLen; i++) {
352       md5_update(padding[i]);
353     }
354     for (i = 0; i < 8; i++) {
355       md5_update(bits[i]);
356     }
358     for (i = 0; i < 4; i++) {
359         for (j = 0; j < 4; j++) {
360             digestBits[i * 4 + j] = and(shr(state[i], (j * 8)) , 0xFF);
361         }
362     } 
365 /* End of the MD5 algorithm */