-
-
Save sukima/5613286 to your computer and use it in GitHub Desktop.
// XORCipher - Super simple encryption using XOR and Base64 | |
// | |
// Depends on [Underscore](http://underscorejs.org/). | |
// | |
// As a warning, this is **not** a secure encryption algorythm. It uses a very | |
// simplistic keystore and will be easy to crack. | |
// | |
// The Base64 algorythm is a modification of the one used in phpjs.org | |
// * http://phpjs.org/functions/base64_encode/ | |
// * http://phpjs.org/functions/base64_decode/ | |
// | |
// Examples | |
// -------- | |
// | |
// XORCipher.encode("test", "foobar"); // => "EgocFhUX" | |
// XORCipher.decode("test", "EgocFhUX"); // => "foobar" | |
// | |
// Copyright © 2013 Devin Weaver <[email protected]> | |
// | |
// This program is free software. It comes without any warranty, to | |
// the extent permitted by applicable law. You can redistribute it | |
// and/or modify it under the terms of the Do What The Fuck You Want | |
// To Public License, Version 2, as published by Sam Hocevar. See | |
// http://www.wtfpl.net/ for more details. | |
/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, strict:true, | |
undef:true, unused:true, curly:true, browser:true, indent:2, maxerr:50 */ | |
/* global _ */ | |
(function(exports) { | |
"use strict"; | |
var XORCipher = { | |
encode: function(key, data) { | |
data = xor_encrypt(key, data); | |
return b64_encode(data); | |
}, | |
decode: function(key, data) { | |
data = b64_decode(data); | |
return xor_decrypt(key, data); | |
} | |
}; | |
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 keyCharAt(key, i) { | |
return key.charCodeAt( Math.floor(i % key.length) ); | |
} | |
function xor_encrypt(key, data) { | |
return _.map(data, function(c, i) { | |
return c.charCodeAt(0) ^ keyCharAt(key, i); | |
}); | |
} | |
function xor_decrypt(key, data) { | |
return _.map(data, function(c, i) { | |
return String.fromCharCode( c ^ keyCharAt(key, i) ); | |
}).join(""); | |
} | |
exports.XORCipher = XORCipher; | |
})(this); |
Thanks a lot for the code. I'm using it for SafeMessage which is an open-source freely-distributed project for exchanging messages securely. An alpha version is now running at http://opentox.ntua.gr/safemsg/create.php.
@alphaville I hope you know this is a highly insecure encryption algorithm. (not meant to be used for encryption of secret messages) You won't be able to exchange message securely...
@idmean XOR is a perfect encryption algorithm as long as the key is longer than data and it is used only once. For example, it is handy when you want to split the data in two parts so that compromising one site will not reveal the message
_.map
? what's _
?
For _.map see:
// Depends on Underscore.
@pfautrero OMG how have I not responded! I'm so sorry. Yeah this should probubly be listed in public domain. How about the WTFPL.
Why not use btoa() and atob() ? Any difference with your code ?
Does not work with UTF8 characters.
XORCipher.decode(XORCipher.encode("abcde абвгде", "1"), "1");
returns abcde 452745
P.S.
Why do you use underscore for this simple function?
Here is encrypt/decrypt functions without underscore dependency:
function xor_encrypt(key, data) {
return data.split('').map(function(c, i) {
return c.charCodeAt(0) ^ keyCharAt(key, i);
});
}
function xor_decrypt(key, data) {
return data.map(function(c, i) {
return String.fromCharCode( c ^ keyCharAt(key, i) );
}).join("");
}
this version doesn't depend on any other library, and it's packed as an object
var XORCipher = {
encode: function (key, data) {
data = this.xor_encrypt(key, data);
return this.b64_encode(data);
},
decode: function (key, data) {
data = this.b64_decode(data);
return this.xor_decrypt(key, data);
},
b64_table: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
b64_encode: function (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 += this.b64_table.charAt(h1) + this.b64_table.charAt(h2) + this.b64_table.charAt(h3) + this.b64_table.charAt(h4);
} while (i < data.length);
r = data.length % 3;
return (r ? enc.slice(0, r - 3) : enc) + "===".slice(r || 3);
},
b64_decode: function (data) {
var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, result = [];
if (!data) { return data; }
data += "";
do {
h1 = this.b64_table.indexOf(data.charAt(i++));
h2 = this.b64_table.indexOf(data.charAt(i++));
h3 = this.b64_table.indexOf(data.charAt(i++));
h4 = this.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;
},
keyCharAt: function (key, i) {
return key.charCodeAt(Math.floor(i % key.length));
},
xor_encrypt: function (key, data) {
let rta = []
for (let i = 0; i < data.length; i++) {
let c = data[i]
rta.push(c.charCodeAt(0) ^ this.keyCharAt(key, i))
}
return rta;
},
xor_decrypt: function (key, data) {
let rta = []
for (let i = 0; i < data.length; i++) {
let c = data[i]
rta.push(String.fromCharCode(c ^ this.keyCharAt(key, i)))
}
return rta.join("")
}
};
Above code with no dependencies run over Google's Closure Compiler and Uglify:
var XORCipher={encode:function(t,e){return e=this.xor_encrypt(t,e),this.b64_encode(e)},decode:function(t,e){return e=this.b64_decode(e),this.xor_decrypt(t,e)},b64_table:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",b64_encode:function(t){var e=0,r="";if(!t)return t;do{var h=t[e++],n=t[e++],i=t[e++],a=h<<16|n<<8|i;h=a>>18&63,n=a>>12&63,i=a>>6&63,a&=63,r+=this.b64_table.charAt(h)+this.b64_table.charAt(n)+this.b64_table.charAt(i)+this.b64_table.charAt(a)}while(e<t.length);return((t=t.length%3)?r.slice(0,t-3):r)+"===".slice(t||3)},b64_decode:function(t){var e=0,r=[];if(!t)return t;t+="";do{var h=this.b64_table.indexOf(t.charAt(e++)),n=this.b64_table.indexOf(t.charAt(e++)),i=this.b64_table.indexOf(t.charAt(e++)),a=this.b64_table.indexOf(t.charAt(e++)),c=h<<18|n<<12|i<<6|a;h=c>>16&255,n=c>>8&255,c&=255,r.push(h),64!==i&&(r.push(n),64!==a&&r.push(c))}while(e<t.length);return r},keyCharAt:function(t,e){return t.charCodeAt(Math.floor(e%t.length))},xor_encrypt:function(t,e){for(var r=[],h=0;h<e.length;h++)r.push(e[h].charCodeAt(0)^this.keyCharAt(t,h));return r},xor_decrypt:function(t,e){for(var r=[],h=0;h<e.length;h++)r.push(String.fromCharCode(e[h]^this.keyCharAt(t,h)));return r.join("")}};
Wow, I don't believe this still gets views! I was so young when I wrote this.
Thank you for this code, it inspired this super simple utility: https://gist.github.com/lyquix-owner/2ad6459672c1b8ec826b0b59f4e220d3
Thank you for this code. It helped me from installing yet another package.
Here is a fixed version that works with non-ACSII (unicode/utf8) characters in string and/or in key and has no dependency on external libraries.
It uses stringToUtf8ByteArray() and utf8ByteArrayToString()
Test: https://jsfiddle.net/vanowm/jczf09ao/
// XORCipher - Super simple encryption using XOR and Base64
//
// As a warning, this is **not** a secure encryption algorithm. It uses a very
// simplistic keystore and will be easy to crack.
//
// The Base64 algorithm is a modification of the one used in phpjs.org
// * http://phpjs.org/functions/base64_encode/
// * http://phpjs.org/functions/base64_decode/
//
// stringToUtf8ByteArray() and utf8ByteArrayToString()
// https://github.com/google/closure-library/blob/466a34e7e2d4cb49ac1c731347e845235d8ce7cc/closure/goog/crypt/crypt.js#L117-L143
// https://github.com/google/closure-library/blob/466a34e7e2d4cb49ac1c731347e845235d8ce7cc/closure/goog/crypt/crypt.js#L151-L178
// Examples
// --------
//
// XORCipher.encode("test", "foobar"); // => "EgocFhUX"
// XORCipher.decode("test", "EgocFhUX"); // => "foobar"
//
// Copyright © 2013 Devin Weaver <[email protected]>
//
// This program is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What The Fuck You Want
// To Public License, Version 2, as published by Sam Hocevar. See
// http://www.wtfpl.net/ for more details.
/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, strict:true,
undef:true, unused:true, curly:true, browser:true, indent:2, maxerr:50 */
/* global _ */
(function(exports) {
"use strict";
var XORCipher = {
encode: function(key, data) {
data = xor_encrypt(key, data);
return b64_encode(data);
},
decode: function(key, data) {
data = b64_decode(data);
return xor_decrypt(key, data);
}
};
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 xor_encrypt(key, data) {
key = stringToUtf8ByteArray(key);
return stringToUtf8ByteArray(data).map(function(c, i) {
return c ^ key[Math.floor(i % key.length)];
});
}
function xor_decrypt(key, data) {
key = stringToUtf8ByteArray(key);
return utf8ByteArrayToString(data.map(function(c, i) {
return c ^ key[Math.floor(i % key.length)];
}));
}
exports.XORCipher = XORCipher;
})(this);
This version generates random encrypted string, meaning even when supplied identical text and key, the generated text will always be different every time it's encrypted (there is 1 in 65534^6 chance it might repeat)
This version accepts an optional third parameter "seed". This parameter will be used to randomize the encrypted output. If an empty string used as seed (or any static string) it will generate static (non-random) encryption output. If no seed provided (undefined) a random generated seed of 6 characters will be used. Provided XORCipher.seed(
nn
)
function can be used to generate random nn long seed. The seed can only contain characters with 1-65535 charcode
i.e.
XORCipher.encode("test", "foobar", XORCipher.seed(10));
will encrypt with 10 characters long seed
Demo:
https://jsfiddle.net/vanowm/7suyfgo4/
// XORCipher - Super simple encryption using XOR and Base64
//
// As a warning, this is **not** a secure encryption algorithm. It uses a very
// simplistic keystore and will be easy to crack.
//
// The Base64 algorithm is a modification of the one used in phpjs.org
// * http://phpjs.org/functions/base64_encode/
// * http://phpjs.org/functions/base64_decode/
//
// stringToUtf8ByteArray() and utf8ByteArrayToString()
// https://github.com/google/closure-library/blob/466a34e7e2d4cb49ac1c731347e845235d8ce7cc/closure/goog/crypt/crypt.js#L117-L143
// https://github.com/google/closure-library/blob/466a34e7e2d4cb49ac1c731347e845235d8ce7cc/closure/goog/crypt/crypt.js#L151-L178
// Examples
// --------
//
// XORCipher.encode("test", "foobar"); // => "EgocFhUX" (random each time)
// XORCipher.decode("test", "EgocFhUX"); // => "foobar"
// XORCipher.encode("test", "foobar", ""); // => "dHdrcGZiYw==" (static each time)
// XORCipher.decode("test", "dHdrcGZiYw=="); // => "foobar"
// XORCipher.encode("test", "foobar", XORCipher.seed(10)); // => "XAIFMUMbeURsFRdyHXMTcQM=" (random each time, 10 char long seed)
// XORCipher.decode("test", "XAIFMUMbeURsFRdyHXMTcQM="); // => "foobar"
//
// Copyright © 2013 Devin Weaver <[email protected]>
//
// This program is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What The Fuck You Want
// To Public License, Version 2, as published by Sam Hocevar. See
// http://www.wtfpl.net/ for more details.
/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, strict:true,
undef:true, unused:true, curly:true, browser:true, indent:2, maxerr:50 */
/* global _ */
(function(exports) {
"use strict";
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(6);
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);
}
exports.XORCipher = XORCipher;
})(this);
Do you have this script in PHP with the functionality of encrypting using random seed? @vanowm
Another version that uses a simple hex encode/decode
TypeScript (JavaScript below)
const XORCipher = {
encode(key: string, plaintext: string) {
const bin = xor_encrypt(key, plaintext);
const hex = Array.from(bin, (b) => b.toString(16).padStart(2, '0')).join('');
return hex;
},
decode(key: string, hexString: string) {
const hexes = hexString.match(/.{2}/g) as string[];
const bin = Uint8Array.from(hexes, (byte) => parseInt(byte, 16));
return xor_decrypt(key, bin);
},
};
function keyCharAt(key: string, i: number) {
return key.charCodeAt(Math.floor(i % key.length));
}
function xor_encrypt(key: string, plaintext: string) {
const bin = new Uint8Array(plaintext.length);
for (let i = 0; i < plaintext.length; i++) {
bin[i] = plaintext.charCodeAt(i) ^ keyCharAt(key, i);
}
return bin;
}
function xor_decrypt(key: string, bin: Uint8Array) {
return Array.from(bin, (c, i) => String.fromCharCode(c ^ keyCharAt(key, i))).join('');
}
const encoded = XORCipher.encode('the lost key', 'Dep Trai Co Gi Sai');
console.log('Encoded:', encoded);
console.log(XORCipher.decode('the lost key', encoded));
JavaScript Version
const XORCipher = {
encode (key, plaintext) {
const bin = xor_encrypt(key, plaintext);
const hex = Array.from(bin, (b)=>b.toString(16).padStart(2, '0')).join('');
return hex;
},
decode (key, hexString) {
const hexes = hexString.match(/.{2}/g);
const bin = Uint8Array.from(hexes, (byte)=>parseInt(byte, 16));
return xor_decrypt(key, bin);
}
};
function keyCharAt(key, i) {
return key.charCodeAt(Math.floor(i % key.length));
}
function xor_encrypt(key, plaintext) {
const bin = new Uint8Array(plaintext.length);
for(let i = 0; i < plaintext.length; i++){
bin[i] = plaintext.charCodeAt(i) ^ keyCharAt(key, i);
}
return bin;
}
function xor_decrypt(key, bin) {
return Array.from(bin, (c, i)=>String.fromCharCode(c ^ keyCharAt(key, i))).join('');
}
const encoded = XORCipher.encode('the lost key', 'Dep Trai Co Gi Sai');
console.log('Encoded:', encoded);
console.log(XORCipher.decode('the lost key', encoded));
Disclaimer: not secure as OP mentioned.
Hi,
What is the license applied on XORCipher.js ? MIT ?
Thanks