File indexing completed on 2024-05-19 06:00:26

0001 /*
0002  * jQuery Cryptography Plug-in
0003  * version: 1.0.0 (24 Sep 2008)
0004  * copyright 2008 Scott Thompson http://www.itsyndicate.ca - scott@itsyndicate.ca
0005  * http://www.opensource.org/licenses/mit-license.php
0006  *
0007  * A set of functions to do some basic cryptography encoding/decoding
0008  * I compiled from some javascripts I found into a jQuery plug-in.
0009  * Thanks go out to the original authors.
0010  *
0011  * Also a big thanks to Wade W. Hedgren http://homepages.uc.edu/~hedgreww
0012  * for the 1.1.1 upgrade to conform correctly to RFC4648 Sec5 url save base64
0013  *
0014  * Changelog: 1.1.0
0015  * - rewrote plugin to use only one item in the namespace
0016  *
0017  * Changelog: 1.1.1
0018  * - added code to base64 to allow URL and Filename Safe Alphabet (RFC4648 Sec5) 
0019  *
0020  * --- Base64 Encoding and Decoding code was written by
0021  *
0022  * Base64 code from Tyler Akins -- http://rumkin.com
0023  * and is placed in the public domain
0024  *
0025  *
0026  * --- MD5 and SHA1 Functions based upon Paul Johnston's javascript libraries.
0027  * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
0028  * Digest Algorithm, as defined in RFC 1321.
0029  * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
0030  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
0031  * Distributed under the BSD License
0032  * See http://pajhome.org.uk/crypt/md5 for more info.
0033  *
0034  * xTea Encrypt and Decrypt
0035  * copyright 2000-2005 Chris Veness
0036  * http://www.movable-type.co.uk
0037  *
0038  *
0039  * Examples:
0040  *
0041         var md5 = $().crypt({method:"md5",source:$("#phrase").val()});
0042         var sha1 = $().crypt({method:"sha1",source:$("#phrase").val()});
0043         var b64 = $().crypt({method:"b64enc",source:$("#phrase").val()});
0044         var b64dec = $().crypt({method:"b64dec",source:b64});
0045         var xtea = $().crypt({method:"xteaenc",source:$("#phrase").val(),keyPass:$("#passPhrase").val()});
0046         var xteadec = $().crypt({method:"xteadec",source:xtea,keyPass:$("#passPhrase").val()});
0047         var xteab64 = $().crypt({method:"xteab64enc",source:$("#phrase").val(),keyPass:$("#passPhrase").val()});
0048         var xteab64dec = $().crypt({method:"xteab64dec",source:xteab64,keyPass:$("#passPhrase").val()});
0049 
0050     You can also pass source this way.
0051     var md5 = $("#idOfSource").crypt({method:"md5"});
0052  *
0053  */
0054 (function($){
0055      $.fn.crypt = function(options) {
0056         var defaults = {
0057             b64Str  : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!-",
0058             strKey  : "123",
0059             method  : "md5",
0060             source  : "",
0061             chrsz   : 8, /* md5 - bits per input character. 8 - ASCII; 16 - Unicode      */
0062             hexcase : 0  /* md5 - hex output format. 0 - lowercase; 1 - uppercase        */
0063         };
0064         
0065         // code to enable URL and Filename Safe Alphabet (RFC4648 Sec5)
0066 /*
0067         if (typeof(options.urlsafe) == 'undefined'){
0068             defaults.b64Str += '+/=';
0069             options.urlsafe = false;
0070         }else if (options.urlsafe){
0071             defaults.b64Str += '-_=';
0072         }else{
0073             defaults.b64Str += '+/=';
0074         }
0075 */
0076         var opts = $.extend(defaults, options);
0077         
0078         // support for $("#name").crypt.....
0079         if (!opts.source) {
0080             var $this = $(this);
0081             // determine if it's a div or a textarea
0082             if ($this.html()) opts.source = $this.html();
0083             else if ($this.val()) opts.source = $this.val();
0084             else {alert("Please provide source text");return false;};
0085         };
0086 
0087         if (opts.method == 'md5') {
0088             return md5(opts);
0089         } else if (opts.method == 'sha1') {
0090             return sha1(opts);
0091         } else if (opts.method == 'b64enc') {
0092             return b64enc(opts);
0093         } else if (opts.method == 'b64dec') {
0094             return b64dec(opts);
0095         } else if (opts.method == 'xteaenc') {
0096             return xteaenc(opts);
0097         } else if (opts.method == 'xteadec') {
0098             return xteadec(opts);
0099         } else if (opts.method == 'xteab64enc') {
0100             var tmpenc = xteaenc(opts);
0101             opts.method = "b64enc";
0102             opts.source = tmpenc;
0103             return b64enc(opts);
0104         } else if (opts.method == 'xteab64dec') {
0105             var tmpdec = b64dec(opts);
0106             opts.method = "xteadec";
0107             opts.source = tmpdec;
0108             return xteadec(opts);
0109         }
0110 
0111 
0112         function b64enc(params) {
0113 
0114             var output = "";
0115             var chr1, chr2, chr3;
0116             var enc1, enc2, enc3, enc4;
0117             var i = 0;
0118 
0119             do {
0120                 chr1 = params.source.charCodeAt(i++);
0121                 chr2 = params.source.charCodeAt(i++);
0122                 chr3 = params.source.charCodeAt(i++);
0123 
0124                 enc1 = chr1 >> 2;
0125                 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
0126                 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
0127                 enc4 = chr3 & 63;
0128 
0129                 if (isNaN(chr2)) {
0130                     enc3 = enc4 = 64;
0131                 } else if (isNaN(chr3)) {
0132                     enc4 = 64;
0133                 };
0134 
0135                 output += params.b64Str.charAt(enc1)
0136                     + params.b64Str.charAt(enc2)
0137                     + params.b64Str.charAt(enc3)
0138                     + params.b64Str.charAt(enc4);
0139 
0140 
0141             } while (i < params.source.length);
0142 
0143             return output;
0144 
0145         };
0146 
0147         function b64dec(params) {
0148                     
0149             var output = "";
0150             var chr1, chr2, chr3;
0151             var enc1, enc2, enc3, enc4;
0152             var i = 0;
0153 
0154             // remove all characters that are not A-Z, a-z, 0-9, !, -, or _
0155             
0156             // remove all characters that are not A-Z, a-z, 0-9, !, -, or _
0157             // params.source = params.source.replace(/[^A-Za-z0-9!_-]/g, "");
0158             
0159             var re = new RegExp ('[^A-Za-z0-9' + params.b64Str.substr(-3) + ']', 'g');
0160             params.source = params.source.replace(re, "");
0161 
0162             do {
0163                 enc1 = params.b64Str.indexOf(params.source.charAt(i++));
0164                 enc2 = params.b64Str.indexOf(params.source.charAt(i++));
0165                 enc3 = params.b64Str.indexOf(params.source.charAt(i++));
0166                 enc4 = params.b64Str.indexOf(params.source.charAt(i++));
0167 
0168                 chr1 = (enc1 << 2) | (enc2 >> 4);
0169                 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
0170                 chr3 = ((enc3 & 3) << 6) | enc4;
0171 
0172                 output = output + String.fromCharCode(chr1);
0173 
0174                 if (enc3 != 64) {
0175                     output = output + String.fromCharCode(chr2);
0176                 }
0177                 if (enc4 != 64) {
0178                     output = output + String.fromCharCode(chr3);
0179                 }
0180             } while (i < params.source.length);
0181 
0182             return output;
0183         };
0184 
0185 
0186         function md5(params) {
0187             /* This is a trimmed version of Paul Johnsons JavaScript
0188              *
0189              * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
0190              * Digest Algorithm, as defined in RFC 1321.
0191              * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
0192              * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
0193              * Distributed under the BSD License
0194              * See http://pajhome.org.uk/crypt/md5 for more info.
0195              */
0196 
0197             //var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
0198             //var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
0199 
0200             return binl2hex(core_md5(str2binl(params.source), params.source.length * params.chrsz));
0201 
0202             /*
0203              * Convert an array of little-endian words to a hex string.
0204              */
0205             function binl2hex(binarray)
0206             {
0207               var hex_tab = params.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
0208               var str = "";
0209               for(var i = 0; i < binarray.length * 4; i++)
0210               {
0211                 str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
0212                        hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
0213               };
0214               return str;
0215             };
0216 
0217             /*
0218              * Calculate the HMAC-MD5, of a key and some data
0219              */
0220             function core_hmac_md5(key, data)
0221             {
0222               var bkey = str2binl(key);
0223               if(bkey.length > 16) bkey = core_md5(bkey, key.length * params.chrsz);
0224 
0225               var ipad = Array(16), opad = Array(16);
0226               for(var i = 0; i < 16; i++)
0227               {
0228                 ipad[i] = bkey[i] ^ 0x36363636;
0229                 opad[i] = bkey[i] ^ 0x5C5C5C5C;
0230               };
0231 
0232               var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * params.chrsz);
0233               return core_md5(opad.concat(hash), 512 + 128);
0234             };
0235 
0236             /*
0237              * Convert a string to an array of little-endian words
0238              * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
0239              */
0240             function str2binl(str)
0241             {
0242               var bin = Array();
0243               var mask = (1 << params.chrsz) - 1;
0244               for(var i = 0; i < str.length * params.chrsz; i += params.chrsz)
0245                 bin[i>>5] |= (str.charCodeAt(i / params.chrsz) & mask) << (i%32);
0246               return bin;
0247             }
0248 
0249 
0250             /*
0251              * Bitwise rotate a 32-bit number to the left.
0252              */
0253             function bit_rol(num, cnt)
0254             {
0255               return (num << cnt) | (num >>> (32 - cnt));
0256             }
0257 
0258 
0259             /*
0260              * These functions implement the four basic operations the algorithm uses.
0261              */
0262             function md5_cmn(q, a, b, x, s, t)
0263             {
0264               return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
0265             }
0266             function md5_ff(a, b, c, d, x, s, t)
0267             {
0268               return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
0269             }
0270             function md5_gg(a, b, c, d, x, s, t)
0271             {
0272               return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
0273             }
0274             function md5_hh(a, b, c, d, x, s, t)
0275             {
0276               return md5_cmn(b ^ c ^ d, a, b, x, s, t);
0277             }
0278             function md5_ii(a, b, c, d, x, s, t)
0279             {
0280               return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
0281             }
0282 
0283             /*
0284              * Calculate the MD5 of an array of little-endian words, and a bit length
0285              */
0286             function core_md5(x, len)
0287             {
0288               /* append padding */
0289               x[len >> 5] |= 0x80 << ((len) % 32);
0290               x[(((len + 64) >>> 9) << 4) + 14] = len;
0291 
0292               var a =  1732584193;
0293               var b = -271733879;
0294               var c = -1732584194;
0295               var d =  271733878;
0296 
0297               for(var i = 0; i < x.length; i += 16)
0298               {
0299                 var olda = a;
0300                 var oldb = b;
0301                 var oldc = c;
0302                 var oldd = d;
0303 
0304                 a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
0305                 d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
0306                 c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
0307                 b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
0308                 a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
0309                 d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
0310                 c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
0311                 b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
0312                 a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
0313                 d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
0314                 c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
0315                 b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
0316                 a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
0317                 d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
0318                 c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
0319                 b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
0320 
0321                 a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
0322                 d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
0323                 c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
0324                 b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
0325                 a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
0326                 d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
0327                 c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
0328                 b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
0329                 a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
0330                 d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
0331                 c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
0332                 b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
0333                 a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
0334                 d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
0335                 c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
0336                 b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
0337 
0338                 a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
0339                 d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
0340                 c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
0341                 b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
0342                 a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
0343                 d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
0344                 c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
0345                 b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
0346                 a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
0347                 d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
0348                 c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
0349                 b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
0350                 a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
0351                 d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
0352                 c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
0353                 b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
0354 
0355                 a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
0356                 d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
0357                 c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
0358                 b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
0359                 a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
0360                 d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
0361                 c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
0362                 b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
0363                 a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
0364                 d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
0365                 c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
0366                 b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
0367                 a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
0368                 d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
0369                 c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
0370                 b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
0371 
0372                 a = safe_add(a, olda);
0373                 b = safe_add(b, oldb);
0374                 c = safe_add(c, oldc);
0375                 d = safe_add(d, oldd);
0376               };
0377               return Array(a, b, c, d);
0378 
0379             };
0380 
0381         };
0382 
0383         /*
0384          * Add integers, wrapping at 2^32. This uses 16-bit operations internally
0385          * to work around bugs in some JS interpreters. (used by md5 and sha1)
0386          */
0387         function safe_add(x, y)
0388         {
0389           var lsw = (x & 0xFFFF) + (y & 0xFFFF);
0390           var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
0391           return (msw << 16) | (lsw & 0xFFFF);
0392         };
0393 
0394         function sha1(params) {
0395             return binb2hex(core_sha1(str2binb(params.source),params.source.length * params.chrsz));
0396 
0397             /*
0398              * Calculate the SHA-1 of an array of big-endian words, and a bit length
0399              */
0400             function core_sha1(x, len)
0401             {
0402               /* append padding */
0403               x[len >> 5] |= 0x80 << (24 - len % 32);
0404               x[((len + 64 >> 9) << 4) + 15] = len;
0405 
0406               var w = Array(80);
0407               var a =  1732584193;
0408               var b = -271733879;
0409               var c = -1732584194;
0410               var d =  271733878;
0411               var e = -1009589776;
0412 
0413               for(var i = 0; i < x.length; i += 16)
0414               {
0415                 var olda = a;
0416                 var oldb = b;
0417                 var oldc = c;
0418                 var oldd = d;
0419                 var olde = e;
0420 
0421                 for(var j = 0; j < 80; j++)
0422                 {
0423                   if(j < 16) w[j] = x[i + j];
0424                   else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
0425                   var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
0426                                    safe_add(safe_add(e, w[j]), sha1_kt(j)));
0427                   e = d;
0428                   d = c;
0429                   c = rol(b, 30);
0430                   b = a;
0431                   a = t;
0432                 }
0433 
0434                 a = safe_add(a, olda);
0435                 b = safe_add(b, oldb);
0436                 c = safe_add(c, oldc);
0437                 d = safe_add(d, oldd);
0438                 e = safe_add(e, olde);
0439               }
0440               return Array(a, b, c, d, e);
0441 
0442             }
0443             /*
0444              * Bitwise rotate a 32-bit number to the left.
0445              */
0446             function rol(num, cnt)
0447             {
0448               return (num << cnt) | (num >>> (32 - cnt));
0449             }
0450 
0451             /*
0452              * Determine the appropriate additive constant for the current iteration
0453              */
0454             function sha1_kt(t)
0455             {
0456               return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
0457                      (t < 60) ? -1894007588 : -899497514;
0458             }
0459             /*
0460              * Perform the appropriate triplet combination function for the current
0461              * iteration
0462              */
0463             function sha1_ft(t, b, c, d)
0464             {
0465               if(t < 20) return (b & c) | ((~b) & d);
0466               if(t < 40) return b ^ c ^ d;
0467               if(t < 60) return (b & c) | (b & d) | (c & d);
0468               return b ^ c ^ d;
0469             }
0470 
0471             /*
0472              * Convert an array of big-endian words to a hex string.
0473              */
0474             function binb2hex(binarray)
0475             {
0476               var hex_tab = params.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
0477               var str = "";
0478               for(var i = 0; i < binarray.length * 4; i++)
0479               {
0480                 str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
0481                        hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
0482               }
0483               return str;
0484             }
0485 
0486 
0487             /*
0488              * Convert an 8-bit or 16-bit string to an array of big-endian words
0489              * In 8-bit function, characters >255 have their hi-byte silently ignored.
0490              */
0491             function str2binb(str)
0492             {
0493               var bin = Array();
0494               var mask = (1 << params.chrsz) - 1;
0495               for(var i = 0; i < str.length * params.chrsz; i += params.chrsz)
0496                 bin[i>>5] |= (str.charCodeAt(i / params.chrsz) & mask) << (32 - params.chrsz - i%32);
0497               return bin;
0498             }
0499 
0500         };
0501 
0502         function xteaenc(params) {
0503             var v = new Array(2), k = new Array(4), s = "", i;
0504 
0505             params.source = escape(params.source);  // use escape() so only have single-byte chars to encode
0506 
0507             // build key directly from 1st 16 chars of strKey
0508             for (var i=0; i<4; i++) k[i] = Str4ToLong(params.strKey.slice(i*4,(i+1)*4));
0509 
0510             for (i=0; i<params.source.length; i+=8) {  // encode strSource into s in 64-bit (8 char) blocks
0511                 v[0] = Str4ToLong(params.source.slice(i,i+4));  // ... note this is 'electronic codebook' mode
0512                 v[1] = Str4ToLong(params.source.slice(i+4,i+8));
0513                 code(v, k);
0514                 s += LongToStr4(v[0]) + LongToStr4(v[1]);
0515             }
0516 
0517             return escCtrlCh(s);
0518             // note: if strSource or strKey are passed as string objects, rather than strings, this
0519             // function will throw an 'Object doesn't support this property or method' error
0520 
0521             function code(v, k) {
0522               // Extended TEA: this is the 1997 revised version of Needham & Wheeler's algorithm
0523               // params: v[2] 64-bit value block; k[4] 128-bit key
0524               var y = v[0], z = v[1];
0525               var delta = 0x9E3779B9, limit = delta*32, sum = 0;
0526 
0527               while (sum != limit) {
0528                 y += (z<<4 ^ z>>>5)+z ^ sum+k[sum & 3];
0529                 sum += delta;
0530                 z += (y<<4 ^ y>>>5)+y ^ sum+k[sum>>>11 & 3];
0531                 // note: unsigned right-shift '>>>' is used in place of original '>>', due to lack
0532                 // of 'unsigned' type declaration in JavaScript (thanks to Karsten Kraus for this)
0533               }
0534               v[0] = y;v[1] = z;
0535             }
0536         };
0537 
0538         function xteadec(params) {
0539             var v = new Array(2), k = new Array(4), s = "", i;
0540 
0541             for (var i=0; i<4; i++) k[i] = Str4ToLong(params.strKey.slice(i*4,(i+1)*4));
0542 
0543             ciphertext = unescCtrlCh(params.source);
0544             for (i=0; i<ciphertext.length; i+=8) {  // decode ciphertext into s in 64-bit (8 char) blocks
0545                 v[0] = Str4ToLong(ciphertext.slice(i,i+4));
0546                 v[1] = Str4ToLong(ciphertext.slice(i+4,i+8));
0547                 decode(v, k);
0548                 s += LongToStr4(v[0]) + LongToStr4(v[1]);
0549             }
0550 
0551             // strip trailing null chars resulting from filling 4-char blocks:
0552             s = s.replace(/\0+$/, '');
0553 
0554             return unescape(s);
0555 
0556 
0557             function decode(v, k) {
0558               var y = v[0], z = v[1];
0559               var delta = 0x9E3779B9, sum = delta*32;
0560 
0561               while (sum != 0) {
0562                 z -= (y<<4 ^ y>>>5)+y ^ sum+k[sum>>>11 & 3];
0563                 sum -= delta;
0564                 y -= (z<<4 ^ z>>>5)+z ^ sum+k[sum & 3];
0565               }
0566               v[0] = y;v[1] = z;
0567             }
0568 
0569         };
0570 
0571             // xtea supporting functions
0572         function Str4ToLong(s) {  // convert 4 chars of s to a numeric long
0573           var v = 0;
0574           for (var i=0; i<4; i++) v |= s.charCodeAt(i) << i*8;
0575           return isNaN(v) ? 0 : v;
0576         };
0577 
0578         function LongToStr4(v) {  // convert a numeric long to 4 char string
0579           var s = String.fromCharCode(v & 0xFF, v>>8 & 0xFF, v>>16 & 0xFF, v>>24 & 0xFF);
0580           return s;
0581         };
0582 
0583         function escCtrlCh(str) {  // escape control chars which might cause problems with encrypted texts
0584           return str.replace(/[\0\t\n\v\f\r\xa0'"!]/g, function(c) {return '!' + c.charCodeAt(0) + '!';});
0585         };
0586 
0587         function unescCtrlCh(str) {  // unescape potentially problematic nulls and control characters
0588           return str.replace(/!\d\d?\d?!/g, function(c) {return String.fromCharCode(c.slice(1,-1));});
0589         };
0590 
0591 
0592 
0593     };
0594 })(jQuery);
0595 
0596