187 lines
4.3 KiB
JavaScript
187 lines
4.3 KiB
JavaScript
|
|
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; |