File Coverage

blib/lib/Javascript/MD5.pm
Criterion Covered Total %
statement 9 24 37.5
branch 0 2 0.0
condition 0 4 0.0
subroutine 3 7 42.8
pod 0 2 0.0
total 12 39 30.7


line stmt bran cond sub pod time code
1             package Javascript::MD5;
2              
3             # Name:
4             # Javascript::MD5.
5             #
6             # Documentation:
7             # POD-style documentation is at the end. Extract it with pod2html.*.
8             #
9             # Reference:
10             # Object Oriented Perl
11             # Damian Conway
12             # Manning
13             # 1-884777-79-1
14             # P 114
15             #
16             # Note:
17             # o Tab = 4 spaces || die.
18             #
19             # Author:
20             # Ron Savage
21             # Home page: http://savage.net.au/index.html
22             #
23             # Licence:
24             # Australian copyright (c) 2004 Ron Savage.
25             #
26             # All Programs of mine are 'OSI Certified Open Source Software';
27             # you can redistribute them and/or modify them under the terms of
28             # The Artistic License, a copy of which is available at:
29             # http://www.opensource.org/licenses/index.html
30              
31 1     1   26066 use strict;
  1         3  
  1         41  
32 1     1   5 use warnings;
  1         2  
  1         31  
33 1     1   6 no warnings 'redefine';
  1         1  
  1         782  
34              
35             require 5.005_62;
36              
37             require Exporter;
38              
39             our @ISA = qw(Exporter);
40              
41             # Items to export into callers namespace by default. Note: do not export
42             # names by default without a very good reason. Use EXPORT_OK instead.
43             # Do not simply export all your public functions/methods/constants.
44              
45             # This allows declaration use Javascript::MD5 ':all';
46             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
47             # will save memory.
48             our %EXPORT_TAGS = ( 'all' => [ qw(
49              
50             ) ] );
51              
52             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
53              
54             our @EXPORT = qw(
55              
56             );
57             our $VERSION = '1.10';
58              
59             # -----------------------------------------------
60              
61             # Preloaded methods go here.
62              
63             # -----------------------------------------------
64              
65             # Encapsulated class data.
66              
67             {
68             my(%_attr_data) =
69             ( # Alphabetical order.
70             );
71              
72             sub _default_for
73             {
74 0     0     my($self, $attr_name) = @_;
75              
76 0           $_attr_data{$attr_name};
77             }
78              
79             sub _standard_keys
80             {
81 0     0     keys %_attr_data;
82             }
83              
84             } # End of encapsulated class data.
85              
86             # -----------------------------------------------
87              
88             sub javascript
89             {
90 0     0 0   my($self, $field_name, $form_number) = @_;
91 0   0       $field_name ||= 'password';
92 0   0       $form_number ||= 0;
93              
94 0           return <
95             /*
96             * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
97             * Digest Algorithm, as defined in RFC 1321.
98             * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
99             * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
100             * Distributed under the BSD License
101             * See http://pajhome.org.uk/crypt/md5 for more info.
102             * Patch by Ron Savage 2004-04-27:
103             * o Add the 3 functions str2hex_md5, str2b64_md5 and str2str_md5().
104             * Note: In V 1.02 of this module, the first function was called
105             * RetMD5 because that's what the Yahoo! programmers called it.
106             */
107              
108             function str2hex_md5()
109             {
110             document.forms[$form_number].$field_name.value = hex_md5(document.forms[$form_number].$field_name.value);
111             return true;
112             }
113              
114             function str2b64_md5()
115             {
116             document.forms[$form_number].$field_name.value = b64_md5(document.forms[$form_number].$field_name.value);
117             return true;
118             }
119              
120             function str2str_md5()
121             {
122             document.forms[$form_number].$field_name.value = str_md5(document.forms[$form_number].$field_name.value);
123             return true;
124             }
125              
126             /*
127             * Configurable variables. You may need to tweak these to be compatible with
128             * the server-side, but the defaults work in most cases.
129             */
130             var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
131             var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
132             var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
133              
134             /*
135             * These are the functions you'll usually want to call.
136             * They take string arguments and return either hex or base-64 encoded strings
137             */
138             function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
139             function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
140             function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
141             function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
142             function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
143             function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
144              
145             /*
146             * Perform a simple self-test to see if the VM is working
147             */
148             function md5_vm_test()
149             {
150             return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
151             }
152              
153             /*
154             * Calculate the MD5 of an array of little-endian words, and a bit length
155             */
156             function core_md5(x, len)
157             {
158             /* append padding */
159             x[len >> 5] |= 0x80 << ((len) % 32);
160             x[(((len + 64) >>> 9) << 4) + 14] = len;
161              
162             var a = 1732584193;
163             var b = -271733879;
164             var c = -1732584194;
165             var d = 271733878;
166              
167             for(var i = 0; i < x.length; i += 16)
168             {
169             var olda = a;
170             var oldb = b;
171             var oldc = c;
172             var oldd = d;
173              
174             a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
175             d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
176             c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
177             b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
178             a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
179             d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
180             c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
181             b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
182             a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
183             d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
184             c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
185             b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
186             a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
187             d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
188             c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
189             b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
190              
191             a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
192             d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
193             c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
194             b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
195             a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
196             d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
197             c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
198             b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
199             a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
200             d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
201             c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
202             b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
203             a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
204             d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
205             c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
206             b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
207              
208             a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
209             d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
210             c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
211             b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
212             a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
213             d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
214             c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
215             b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
216             a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
217             d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
218             c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
219             b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
220             a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
221             d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
222             c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
223             b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
224              
225             a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
226             d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
227             c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
228             b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
229             a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
230             d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
231             c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
232             b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
233             a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
234             d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
235             c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
236             b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
237             a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
238             d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
239             c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
240             b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
241              
242             a = safe_add(a, olda);
243             b = safe_add(b, oldb);
244             c = safe_add(c, oldc);
245             d = safe_add(d, oldd);
246             }
247             return Array(a, b, c, d);
248              
249             }
250              
251             /*
252             * These functions implement the four basic operations the algorithm uses.
253             */
254             function md5_cmn(q, a, b, x, s, t)
255             {
256             return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
257             }
258             function md5_ff(a, b, c, d, x, s, t)
259             {
260             return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
261             }
262             function md5_gg(a, b, c, d, x, s, t)
263             {
264             return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
265             }
266             function md5_hh(a, b, c, d, x, s, t)
267             {
268             return md5_cmn(b ^ c ^ d, a, b, x, s, t);
269             }
270             function md5_ii(a, b, c, d, x, s, t)
271             {
272             return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
273             }
274              
275             /*
276             * Calculate the HMAC-MD5, of a key and some data
277             */
278             function core_hmac_md5(key, data)
279             {
280             var bkey = str2binl(key);
281             if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
282              
283             var ipad = Array(16), opad = Array(16);
284             for(var i = 0; i < 16; i++)
285             {
286             ipad[i] = bkey[i] ^ 0x36363636;
287             opad[i] = bkey[i] ^ 0x5C5C5C5C;
288             }
289              
290             var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
291             return core_md5(opad.concat(hash), 512 + 128);
292             }
293              
294             /*
295             * Add integers, wrapping at 2^32. This uses 16-bit operations internally
296             * to work around bugs in some JS interpreters.
297             */
298             function safe_add(x, y)
299             {
300             var lsw = (x & 0xFFFF) + (y & 0xFFFF);
301             var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
302             return (msw << 16) | (lsw & 0xFFFF);
303             }
304              
305             /*
306             * Bitwise rotate a 32-bit number to the left.
307             */
308             function bit_rol(num, cnt)
309             {
310             return (num << cnt) | (num >>> (32 - cnt));
311             }
312              
313             /*
314             * Convert a string to an array of little-endian words
315             * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
316             */
317             function str2binl(str)
318             {
319             var bin = Array();
320             var mask = (1 << chrsz) - 1;
321             for(var i = 0; i < str.length * chrsz; i += chrsz)
322             bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
323             return bin;
324             }
325              
326             /*
327             * Convert an array of little-endian words to a string
328             */
329             function binl2str(bin)
330             {
331             var str = "";
332             var mask = (1 << chrsz) - 1;
333             for(var i = 0; i < bin.length * 32; i += chrsz)
334             str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
335             return str;
336             }
337              
338             /*
339             * Convert an array of little-endian words to a hex string.
340             */
341             function binl2hex(binarray)
342             {
343             var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
344             var str = "";
345             for(var i = 0; i < binarray.length * 4; i++)
346             {
347             str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
348             hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
349             }
350             return str;
351             }
352              
353             /*
354             * Convert an array of little-endian words to a base-64 string
355             */
356             function binl2b64(binarray)
357             {
358             var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
359             var str = "";
360             for(var i = 0; i < binarray.length * 4; i += 3)
361             {
362             var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
363             | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
364             | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
365             for(var j = 0; j < 4; j++)
366             {
367             if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
368             else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
369             }
370             }
371             return str;
372             }
373             EOS
374              
375             } # End of javascript.
376              
377             # -----------------------------------------------
378              
379             sub new
380             {
381 0     0 0   my($class, %arg) = @_;
382 0           my($self) = bless({}, $class);
383              
384 0           for my $attr_name ($self -> _standard_keys() )
385             {
386 0           my($arg_name) = $attr_name =~ /^_(.*)/;
387              
388 0 0         if (exists($arg{$arg_name}) )
389             {
390 0           $$self{$attr_name} = $arg{$arg_name};
391             }
392             else
393             {
394 0           $$self{$attr_name} = $self -> _default_for($attr_name);
395             }
396             }
397              
398 0           $self;
399              
400             } # End of new.
401              
402             # -----------------------------------------------
403              
404             1;
405              
406             __END__