var XORCipher = { encode: function (key, data, seed) { data = xor_encrypt(key, data, seed); return b64_encode(data); }, decode: function (key, data) { data = b64_decode(data); return xor_decrypt(key, data); }, seed: function (n) { return randString(n); }, }; function stringToUtf8ByteArray(str) { var out = [], p = 0; for (var i = 0; i < str.length; i++) { var c = str.charCodeAt(i); if (c < 128) { out[p++] = c; } else if (c < 2048) { out[p++] = (c >> 6) | 192; out[p++] = (c & 63) | 128; } else if ( (c & 0xfc00) == 0xd800 && i + 1 < str.length && (str.charCodeAt(i + 1) & 0xfc00) == 0xdc00 ) { // Surrogate Pair c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff); out[p++] = (c >> 18) | 240; out[p++] = ((c >> 12) & 63) | 128; out[p++] = ((c >> 6) & 63) | 128; out[p++] = (c & 63) | 128; } else { out[p++] = (c >> 12) | 224; out[p++] = ((c >> 6) & 63) | 128; out[p++] = (c & 63) | 128; } } return out; } function utf8ByteArrayToString(bytes) { // array of bytes var out = [], pos = 0, c = 0; while (pos < bytes.length) { var c1 = bytes[pos++]; if (c1 < 128) { out[c++] = String.fromCharCode(c1); } else if (c1 > 191 && c1 < 224) { var c2 = bytes[pos++]; out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)); } else if (c1 > 239 && c1 < 365) { // Surrogate Pair var c2 = bytes[pos++]; var c3 = bytes[pos++]; var c4 = bytes[pos++]; var u = (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) - 0x10000; out[c++] = String.fromCharCode(0xd800 + (u >> 10)); out[c++] = String.fromCharCode(0xdc00 + (u & 1023)); } else { var c2 = bytes[pos++]; var c3 = bytes[pos++]; out[c++] = String.fromCharCode( ((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63) ); } } return out.join(""); } var b64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; function b64_encode(data) { var o1, o2, o3, h1, h2, h3, h4, bits, r, i = 0, enc = ""; if (!data) { return data; } do { o1 = data[i++]; o2 = data[i++]; o3 = data[i++]; bits = (o1 << 16) | (o2 << 8) | o3; h1 = (bits >> 18) & 0x3f; h2 = (bits >> 12) & 0x3f; h3 = (bits >> 6) & 0x3f; h4 = bits & 0x3f; enc += b64_table.charAt(h1) + b64_table.charAt(h2) + b64_table.charAt(h3) + b64_table.charAt(h4); } while (i < data.length); r = data.length % 3; return (r ? enc.slice(0, r - 3) : enc) + "===".slice(r || 3); } function b64_decode(data) { var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, result = []; if (!data) { return data; } data += ""; do { h1 = b64_table.indexOf(data.charAt(i++)); h2 = b64_table.indexOf(data.charAt(i++)); h3 = b64_table.indexOf(data.charAt(i++)); h4 = b64_table.indexOf(data.charAt(i++)); bits = (h1 << 18) | (h2 << 12) | (h3 << 6) | h4; o1 = (bits >> 16) & 0xff; o2 = (bits >> 8) & 0xff; o3 = bits & 0xff; result.push(o1); if (h3 !== 64) { result.push(o2); if (h4 !== 64) { result.push(o3); } } } while (i < data.length); return result; } function rand(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function randString(n) { var r = ""; for (var i = 0; i < n; i++) r += String.fromCharCode(rand(1, 65535)); return r; } function xor_encrypt(key, data, seed) { if (typeof seed == "undefined") seed = randString(32); var d = stringToUtf8ByteArray(seed + String.fromCharCode(0) + data), k = stringToUtf8ByteArray(key), r = []; for (var i = 0; i < d.length; i++) r[i] = r[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)]; return r; } function xor_decrypt(key, data) { var d = data, k = stringToUtf8ByteArray(key), r = []; for (var i = 0; i < d.length; i++) r[i] = d[i - 1] ^ d[i] ^ k[Math.floor(i % k.length)]; r.splice(0, r.indexOf(0) + 1); return utf8ByteArrayToString(r); } export default XORCipher;