Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- /* Block TEA (xxtea) Tiny Encryption Algorithm implementation in JavaScript */
- /* (c) Chris Veness 2002-2012: www.movable-type.co.uk/tea-block.html */
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- /* Algorithm: David Wheeler & Roger Needham, Cambridge University Computer Lab */
- /* http://www.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html (1994) */
- /* http://www.cl.cam.ac.uk/ftp/users/djw3/xtea.ps (1997) */
- /* http://www.cl.cam.ac.uk/ftp/users/djw3/xxtea.ps (1998) */
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- var Tea = {}; // Tea namespace
- /*
- * encrypt text using Corrected Block TEA (xxtea) algorithm
- *
- * @param {string} plaintext String to be encrypted (multi-byte safe)
- * @param {string} password Password to be used for encryption (1st 16 chars)
- * @returns {string} encrypted text
- */
- Tea.encrypt = function(plaintext, password) {
- if (plaintext.length == 0) return (''); // nothing to encrypt
- // convert string to array of longs after converting any multi-byte chars to UTF-8
- var v = Tea.strToLongs(Utf8.encode(plaintext));
- if (v.length <= 1) v[1] = 0; // algorithm doesn't work for n<2 so fudge by adding a null
- // simply convert first 16 chars of password as key
- var k = Tea.strToLongs(Utf8.encode(password).slice(0, 16));
- var n = v.length;
- // ---- <TEA coding> ----
- var z = v[n - 1],
- y = v[0],
- delta = 0x9E3779B9;
- var mx, e, q = Math.floor(6 + 52 / n),
- sum = 0;
- while (q-- > 0) { // 6 + 52/n operations gives between 6 & 32 mixes on each word
- sum += delta;
- e = sum >>> 2 & 3;
- for (var p = 0; p < n; p++) {
- y = v[(p + 1) % n];
- mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
- z = v[p] += mx;
- }
- }
- // ---- </TEA> ----
- var ciphertext = Tea.longsToStr(v);
- return Base64.encode(ciphertext);
- }
- /*
- * decrypt text using Corrected Block TEA (xxtea) algorithm
- *
- * @param {string} ciphertext String to be decrypted
- * @param {string} password Password to be used for decryption (1st 16 chars)
- * @returns {string} decrypted text
- */
- Tea.decrypt = function(ciphertext, password) {
- if (ciphertext.length == 0) return ('');
- var v = Tea.strToLongs(Base64.decode(ciphertext));
- var k = Tea.strToLongs(Utf8.encode(password).slice(0, 16));
- var n = v.length;
- // ---- <TEA decoding> ----
- var z = v[n - 1],
- y = v[0],
- delta = 0x9E3779B9;
- var mx, e, q = Math.floor(6 + 52 / n),
- sum = q * delta;
- while (sum != 0) {
- e = sum >>> 2 & 3;
- for (var p = n - 1; p >= 0; p--) {
- z = v[p > 0 ? p - 1 : n - 1];
- mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
- y = v[p] -= mx;
- }
- sum -= delta;
- }
- // ---- </TEA> ----
- var plaintext = Tea.longsToStr(v);
- // strip trailing null chars resulting from filling 4-char blocks:
- plaintext = plaintext.replace(/\0+$/, '');
- return Utf8.decode(plaintext);
- }
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- // supporting functions
- Tea.strToLongs = function(s) { // convert string to array of longs, each containing 4 chars
- // note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
- var l = new Array(Math.ceil(s.length / 4));
- for (var i = 0; i < l.length; i++) {
- // note little-endian encoding - endianness is irrelevant as long as
- // it is the same in longsToStr()
- l[i] = s.charCodeAt(i * 4) + (s.charCodeAt(i * 4 + 1) << 8) + (s.charCodeAt(i * 4 + 2) << 16) + (s.charCodeAt(i * 4 + 3) << 24);
- }
- return l; // note running off the end of the string generates nulls since
- } // bitwise operators treat NaN as 0
- Tea.longsToStr = function(l) { // convert array of longs back to string
- var a = new Array(l.length);
- for (var i = 0; i < l.length; i++) {
- a[i] = String.fromCharCode(l[i] & 0xFF, l[i] >>> 8 & 0xFF, l[i] >>> 16 & 0xFF, l[i] >>> 24 & 0xFF);
- }
- return a.join(''); // use Array.join() rather than repeated string appends for efficiency in IE
- }
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- /* Base64 class: Base 64 encoding / decoding (c) Chris Veness 2002-2012 */
- /* note: depends on Utf8 class */
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- var Base64 = {}; // Base64 namespace
- Base64.code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- /**
- * Encode string into Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648]
- * (instance method extending String object). As per RFC 4648, no newlines are added.
- *
- * @param {String} str The string to be encoded as base-64
- * @param {Boolean} [utf8encode=false] Flag to indicate whether str is Unicode string to be encoded
- * to UTF8 before conversion to base64; otherwise string is assumed to be 8-bit characters
- * @returns {String} Base64-encoded string
- */
- Base64.encode = function(str, utf8encode) { // http://tools.ietf.org/html/rfc4648
- utf8encode = (typeof utf8encode == 'undefined') ? false : utf8encode;
- var o1, o2, o3, bits, h1, h2, h3, h4, e = [],
- pad = '',
- c, plain, coded;
- var b64 = Base64.code;
- plain = utf8encode ? Utf8.encode(str) : str;
- c = plain.length % 3; // pad string to length of multiple of 3
- if (c > 0) {
- while (c++ < 3) {
- pad += '=';
- plain += '\0';
- }
- }
- // note: doing padding here saves us doing special-case packing for trailing 1 or 2 chars
- for (c = 0; c < plain.length; c += 3) { // pack three octets into four hexets
- o1 = plain.charCodeAt(c);
- o2 = plain.charCodeAt(c + 1);
- o3 = plain.charCodeAt(c + 2);
- bits = o1 << 16 | o2 << 8 | o3;
- h1 = bits >> 18 & 0x3f;
- h2 = bits >> 12 & 0x3f;
- h3 = bits >> 6 & 0x3f;
- h4 = bits & 0x3f;
- // use hextets to index into code string
- e[c / 3] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
- }
- coded = e.join(''); // join() is far faster than repeated string concatenation in IE
- // replace 'A's from padded nulls with '='s
- coded = coded.slice(0, coded.length - pad.length) + pad;
- return coded;
- }
- /**
- * Decode string from Base64, as defined by RFC 4648 [http://tools.ietf.org/html/rfc4648]
- * (instance method extending String object). As per RFC 4648, newlines are not catered for.
- *
- * @param {String} str The string to be decoded from base-64
- * @param {Boolean} [utf8decode=false] Flag to indicate whether str is Unicode string to be decoded
- * from UTF8 after conversion from base64
- * @returns {String} decoded string
- */
- Base64.decode = function(str, utf8decode) {
- utf8decode = (typeof utf8decode == 'undefined') ? false : utf8decode;
- var o1, o2, o3, h1, h2, h3, h4, bits, d = [],
- plain, coded;
- var b64 = Base64.code;
- coded = utf8decode ? Utf8.decode(str) : str;
- for (var c = 0; c < coded.length; c += 4) { // unpack four hexets into three octets
- h1 = b64.indexOf(coded.charAt(c));
- h2 = b64.indexOf(coded.charAt(c + 1));
- h3 = b64.indexOf(coded.charAt(c + 2));
- h4 = b64.indexOf(coded.charAt(c + 3));
- bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
- o1 = bits >>> 16 & 0xff;
- o2 = bits >>> 8 & 0xff;
- o3 = bits & 0xff;
- d[c / 4] = String.fromCharCode(o1, o2, o3);
- // check for padding
- if (h4 == 0x40) d[c / 4] = String.fromCharCode(o1, o2);
- if (h3 == 0x40) d[c / 4] = String.fromCharCode(o1);
- }
- plain = d.join(''); // join() is far faster than repeated string concatenation in IE
- return utf8decode ? Utf8.decode(plain) : plain;
- }
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- /* Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple */
- /* single-byte character encoding (c) Chris Veness 2002-2012 */
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- var Utf8 = {}; // Utf8 namespace
- /**
- * Encode multi-byte Unicode string into utf-8 multiple single-byte characters
- * (BMP / basic multilingual plane only)
- *
- * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars
- *
- * @param {String} strUni Unicode string to be encoded as UTF-8
- * @returns {String} encoded string
- */
- Utf8.encode = function(strUni) {
- // use regular expressions & String.replace callback function for better efficiency
- // than procedural approaches
- var strUtf = strUni.replace(/[\u0080-\u07ff]/g, // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz
- function(c) {
- var cc = c.charCodeAt(0);
- return String.fromCharCode(0xc0 | cc >> 6, 0x80 | cc & 0x3f);
- });
- strUtf = strUtf.replace(/[\u0800-\uffff]/g, // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz
- function(c) {
- var cc = c.charCodeAt(0);
- return String.fromCharCode(0xe0 | cc >> 12, 0x80 | cc >> 6 & 0x3F, 0x80 | cc & 0x3f);
- });
- return strUtf;
- }
- /**
- * Decode utf-8 encoded string back into multi-byte Unicode characters
- *
- * @param {String} strUtf UTF-8 string to be decoded back to Unicode
- * @returns {String} decoded string
- */
- Utf8.decode = function(strUtf) {
- // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char!
- var strUni = strUtf.replace(/[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars
- function(c) { // (note parentheses for precence)
- var cc = ((c.charCodeAt(0) & 0x0f) << 12) | ((c.charCodeAt(1) & 0x3f) << 6) | (c.charCodeAt(2) & 0x3f);
- return String.fromCharCode(cc);
- });
- strUni = strUni.replace(/[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars
- function(c) { // (note parentheses for precence)
- var cc = (c.charCodeAt(0) & 0x1f) << 6 | c.charCodeAt(1) & 0x3f;
- return String.fromCharCode(cc);
- });
- return strUni;
- }
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement