Cleaner code, one more step forward
[jigdo-ivory.git] / jigsum.js
blobfd475ce72f48c4f253095df15648f2c4e4e8a81e
1 jig = new function jig() /* jigsum "globals" */
3     this.b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
4     this.chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
6                        /* jig.tab is modified to use jigsum -_ instead of +/     */
7     this.tab     = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
9     this.mask = (1 << this.chrsz) - 1;
10     this.speed   = 300;  /* higher is better, but can cause timeout problems */
11     this.fid = 0;        /* timeout id holder                                */
12     this.errors = 0;
15  *  This object holds the intermediate variables needed for core_md5().
16  *  When calculating large md5sums, timeouts occur.  Periodically calling
17  *  the function solves this issue, as a result this object is used.
18  */
19 j = new function Jigsum()
21     this.set = function(s, t)
22     {
23         this.str = s;
24         this.tgt = t;
25         this.lock = true;
26     }
27     
28     this.reset = function()
29     {
30         this.a =  1732584193;
31         this.b = -271733879;
32         this.c = -1732584194;
33         this.d =  271733878;
34         this.i =  0;
35         this.t =  0;
36         this.x =  Array();
37     
38         this.len  = 0;
39         this.lock = false;
40         this.sum  = "";         /* this is the result sum */
41         this.str  = "";         /* be sure to set this before calling jig_md5 */
42         this.tgt  = "";         /* this is the target sum */
43     }
44     
45     this.reset();
49  *  This is the function to be called,
50  *  checksum is found at j.sum
51  */
52 function jig_md5()
54     j.len = j.str.length * jig.chrsz;
55     jig.fid = setTimeout("str2binl()", 1);
59  *  This is where the magic happens,  If timeouts occur, lower jig.speed
60  */
61 function core_md5()
63     if(jig.fid)
64         clearTimeout(jig.fid);
65     jig.fid = 0;
66     count = 0;
67     new_time = new Date();
68     minutes = Math.floor((new_time - cur_time)/60000);
69     seconds = Math.floor((new_time - cur_time)/1000) % 60;
70     document.getElementById('msg').innerHTML = 'Time elapsed: ' + minutes +
71                 ' minutes and ' + seconds + ' seconds.';
73     while(j.i < j.x.length && count < jig.speed)
74     {
75         var olda = j.a;
76         var oldb = j.b;
77         var oldc = j.c;
78         var oldd = j.d;
80         j.a = md5_ff(j.a, j.b, j.c, j.d, j.x[j.i+ 0], 7 , -680876936);
81         j.d = md5_ff(j.d, j.a, j.b, j.c, j.x[j.i+ 1], 12, -389564586);
82         j.c = md5_ff(j.c, j.d, j.a, j.b, j.x[j.i+ 2], 17,  606105819);
83         j.b = md5_ff(j.b, j.c, j.d, j.a, j.x[j.i+ 3], 22, -1044525330);
84         j.a = md5_ff(j.a, j.b, j.c, j.d, j.x[j.i+ 4], 7 , -176418897);
85         j.d = md5_ff(j.d, j.a, j.b, j.c, j.x[j.i+ 5], 12,  1200080426);
86         j.c = md5_ff(j.c, j.d, j.a, j.b, j.x[j.i+ 6], 17, -1473231341);
87         j.b = md5_ff(j.b, j.c, j.d, j.a, j.x[j.i+ 7], 22, -45705983);
88         j.a = md5_ff(j.a, j.b, j.c, j.d, j.x[j.i+ 8], 7 ,  1770035416);
89         j.d = md5_ff(j.d, j.a, j.b, j.c, j.x[j.i+ 9], 12, -1958414417);
90         j.c = md5_ff(j.c, j.d, j.a, j.b, j.x[j.i+10], 17, -42063);
91         j.b = md5_ff(j.b, j.c, j.d, j.a, j.x[j.i+11], 22, -1990404162);
92         j.a = md5_ff(j.a, j.b, j.c, j.d, j.x[j.i+12], 7 ,  1804603682);
93         j.d = md5_ff(j.d, j.a, j.b, j.c, j.x[j.i+13], 12, -40341101);
94         j.c = md5_ff(j.c, j.d, j.a, j.b, j.x[j.i+14], 17, -1502002290);
95         j.b = md5_ff(j.b, j.c, j.d, j.a, j.x[j.i+15], 22,  1236535329);
96     
97         j.a = md5_gg(j.a, j.b, j.c, j.d, j.x[j.i+ 1], 5 , -165796510);
98         j.d = md5_gg(j.d, j.a, j.b, j.c, j.x[j.i+ 6], 9 , -1069501632);
99         j.c = md5_gg(j.c, j.d, j.a, j.b, j.x[j.i+11], 14,  643717713);
100         j.b = md5_gg(j.b, j.c, j.d, j.a, j.x[j.i+ 0], 20, -373897302);
101         j.a = md5_gg(j.a, j.b, j.c, j.d, j.x[j.i+ 5], 5 , -701558691);
102         j.d = md5_gg(j.d, j.a, j.b, j.c, j.x[j.i+10], 9 ,  38016083);
103         j.c = md5_gg(j.c, j.d, j.a, j.b, j.x[j.i+15], 14, -660478335);
104         j.b = md5_gg(j.b, j.c, j.d, j.a, j.x[j.i+ 4], 20, -405537848);
105         j.a = md5_gg(j.a, j.b, j.c, j.d, j.x[j.i+ 9], 5 ,  568446438);
106         j.d = md5_gg(j.d, j.a, j.b, j.c, j.x[j.i+14], 9 , -1019803690);
107         j.c = md5_gg(j.c, j.d, j.a, j.b, j.x[j.i+ 3], 14, -187363961);
108         j.b = md5_gg(j.b, j.c, j.d, j.a, j.x[j.i+ 8], 20,  1163531501);
109         j.a = md5_gg(j.a, j.b, j.c, j.d, j.x[j.i+13], 5 , -1444681467);
110         j.d = md5_gg(j.d, j.a, j.b, j.c, j.x[j.i+ 2], 9 , -51403784);
111         j.c = md5_gg(j.c, j.d, j.a, j.b, j.x[j.i+ 7], 14,  1735328473);
112         j.b = md5_gg(j.b, j.c, j.d, j.a, j.x[j.i+12], 20, -1926607734);
113     
114         j.a = md5_hh(j.a, j.b, j.c, j.d, j.x[j.i+ 5], 4 , -378558);
115         j.d = md5_hh(j.d, j.a, j.b, j.c, j.x[j.i+ 8], 11, -2022574463);
116         j.c = md5_hh(j.c, j.d, j.a, j.b, j.x[j.i+11], 16,  1839030562);
117         j.b = md5_hh(j.b, j.c, j.d, j.a, j.x[j.i+14], 23, -35309556);
118         j.a = md5_hh(j.a, j.b, j.c, j.d, j.x[j.i+ 1], 4 , -1530992060);
119         j.d = md5_hh(j.d, j.a, j.b, j.c, j.x[j.i+ 4], 11,  1272893353);
120         j.c = md5_hh(j.c, j.d, j.a, j.b, j.x[j.i+ 7], 16, -155497632);
121         j.b = md5_hh(j.b, j.c, j.d, j.a, j.x[j.i+10], 23, -1094730640);
122         j.a = md5_hh(j.a, j.b, j.c, j.d, j.x[j.i+13], 4 ,  681279174);
123         j.d = md5_hh(j.d, j.a, j.b, j.c, j.x[j.i+ 0], 11, -358537222);
124         j.c = md5_hh(j.c, j.d, j.a, j.b, j.x[j.i+ 3], 16, -722521979);
125         j.b = md5_hh(j.b, j.c, j.d, j.a, j.x[j.i+ 6], 23,  76029189);
126         j.a = md5_hh(j.a, j.b, j.c, j.d, j.x[j.i+ 9], 4 , -640364487);
127         j.d = md5_hh(j.d, j.a, j.b, j.c, j.x[j.i+12], 11, -421815835);
128         j.c = md5_hh(j.c, j.d, j.a, j.b, j.x[j.i+15], 16,  530742520);
129         j.b = md5_hh(j.b, j.c, j.d, j.a, j.x[j.i+ 2], 23, -995338651);
130     
131         j.a = md5_ii(j.a, j.b, j.c, j.d, j.x[j.i+ 0], 6 , -198630844);
132         j.d = md5_ii(j.d, j.a, j.b, j.c, j.x[j.i+ 7], 10,  1126891415);
133         j.c = md5_ii(j.c, j.d, j.a, j.b, j.x[j.i+14], 15, -1416354905);
134         j.b = md5_ii(j.b, j.c, j.d, j.a, j.x[j.i+ 5], 21, -57434055);
135         j.a = md5_ii(j.a, j.b, j.c, j.d, j.x[j.i+12], 6 ,  1700485571);
136         j.d = md5_ii(j.d, j.a, j.b, j.c, j.x[j.i+ 3], 10, -1894986606);
137         j.c = md5_ii(j.c, j.d, j.a, j.b, j.x[j.i+10], 15, -1051523);
138         j.b = md5_ii(j.b, j.c, j.d, j.a, j.x[j.i+ 1], 21, -2054922799);
139         j.a = md5_ii(j.a, j.b, j.c, j.d, j.x[j.i+ 8], 6 ,  1873313359);
140         j.d = md5_ii(j.d, j.a, j.b, j.c, j.x[j.i+15], 10, -30611744);
141         j.c = md5_ii(j.c, j.d, j.a, j.b, j.x[j.i+ 6], 15, -1560198380);
142         j.b = md5_ii(j.b, j.c, j.d, j.a, j.x[j.i+13], 21,  1309151649);
143         j.a = md5_ii(j.a, j.b, j.c, j.d, j.x[j.i+ 4], 6 , -145523070);
144         j.d = md5_ii(j.d, j.a, j.b, j.c, j.x[j.i+11], 10, -1120210379);
145         j.c = md5_ii(j.c, j.d, j.a, j.b, j.x[j.i+ 2], 15,  718787259);
146         j.b = md5_ii(j.b, j.c, j.d, j.a, j.x[j.i+ 9], 21, -343485551);
147     
148         j.a = safe_add(j.a, olda);
149         j.b = safe_add(j.b, oldb);
150         j.c = safe_add(j.c, oldc);
151         j.d = safe_add(j.d, oldd);
152         
153         j.i += 16;
154         count += 1;
155     }
157     if(j.i < j.x.length)                    //test for continue looping
158         jig.fid = setTimeout("core_md5()", 1);
159     else                                    //otherwise, move to next piece
160     {
161         j.x   = Array(j.a, j.b, j.c, j.d);
162         j.str = "";
163         j.i   = 0;
164         jig.fid = setTimeout("binl2b64()", 1);
165     }
169  * These functions implement the four basic operations the algorithm uses.
170  */
171 function md5_cmn(q, a, b, x, s, t)
173   return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
175 function md5_ff(a, b, c, d, x, s, t)
177   return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
179 function md5_gg(a, b, c, d, x, s, t)
181   return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
183 function md5_hh(a, b, c, d, x, s, t)
185   return md5_cmn(b ^ c ^ d, a, b, x, s, t);
187 function md5_ii(a, b, c, d, x, s, t)
189   return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
193  * Add integers, wrapping at 2^32. This uses 16-bit operations internally
194  * to work around bugs in some JS interpreters.
195  */
196 function safe_add(x, y)
198   var lsw = (x & 0xFFFF) + (y & 0xFFFF);
199   var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
200   return (msw << 16) | (lsw & 0xFFFF);
204  * Bitwise rotate a 32-bit number to the left.
205  */
206 function bit_rol(num, cnt)
208   return (num << cnt) | (num >>> (32 - cnt));
212  * Convert a string to an array of little-endian words
213  * If jig.chrsz is ASCII, characters >255 have their hi-byte silently ignored.
214  */
215 function str2binl()
217     if(jig.fid)
218         clearTimeout(jig.fid);
219     jig.fid = 0;
220     count = 0;
222     while(j.i < j.len && count < jig.speed * 500)
223     {
224         j.x[j.i>>5] |= (j.str.charCodeAt(j.i / jig.chrsz) & jig.mask) << (j.i%32);
225         j.i   += jig.chrsz;
226         count += 1;
227     }
229     if(j.i < j.len)
230         jig.fid = setTimeout("str2binl()", 1);
231     else
232     {
233         j.i = 0;
234         /* append padding */
235         j.x[j.len >> 5] |= 0x80 << ((j.len) % 32);
236         j.x[(((j.len + 64) >>> 9) << 4) + 14] = j.len;
237         jig.fid = setTimeout("core_md5()", 1);
238     }
241 function binl2b64()
243     if(jig.fid)
244         clearTimeout(jig.fid);
245     while(j.i < j.x.length * 4)
246     {
247         j.t = (((j.x[j.i   >> 2] >> 8 * ( j.i   %4)) & 0xFF) << 16)
248                 | (((j.x[j.i+1 >> 2] >> 8 * ((j.i+1)%4)) & 0xFF) << 8 )
249                 |  ((j.x[j.i+2 >> 2] >> 8 * ((j.i+2)%4)) & 0xFF);
250         for(var k = 0; k < 4; k++)
251         {
252             if(j.i * 8 + k * 6 > j.x.length * 32) j.str += jig.b64pad;
253             else j.str += jig.tab.charAt((j.t >> 6*(3-k)) & 0x3F);
254         }
255         j.i += 3;
256     }
258     j.sum = j.str;
260     document.getElementById('sum').innerHTML = j.sum;
261     if(j.sum == j.tgt)
262         document.getElementById('sum').innerHTML += ' +match:success+';
263     else
264         jig.errors += 1;
265     document.getElementById('sum').innerHTML += '<br>' + jig.errors + ' errors.';
266     j.lock = false;
267     fid = setTimeout("task()", 1);