Last active
December 21, 2024 03:07
-
-
Save sukima/5613286 to your computer and use it in GitHub Desktop.
A Super simple encryption cipher using XOR and Base64 in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); |
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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Do you have this script in PHP with the functionality of encrypting using random seed? @vanowm