I've implemented the below as mask for some data:
function jEncryptDecrypt(data,key) {
let jKey = ''
let bytKey = [];
let bytData = [];
for (let i = 1; i < (data.length/key.length) +1; i++) {
jKey = jKey + key;
}
let str = jKey.substring(0, data.length);
for (let i = 0; i < str.length; ++i) {
var code = str.charCodeAt(i);
bytKey = bytKey.concat([code & 0xff, code / 256 >>> 0]);
}
let str2 = data
for (let i = 0; i < str2.length; ++i) {
var code = str2.charCodeAt(i);
bytData = bytData.concat([code & 0xff, code / 256 >>> 0]);
}
for (let i = 0; i < bytData.length; ++i) {
bytData[i] = bytData[i] ^ bytKey[i];
}
str3 = String.fromCharCode(...bytData)
str3 = str3.replace(/\0/g, '');
return str3;
}
For some outputs the bytes in bytData map to escape characters - depending on where I run the code I either get the character (JSFiddle) or I get \uXXXX (third party application). The output could end up being dealt with on different platforms/languages, so ideally I'd like to avoid special characters and just have characters in the 32 to 126 unicode range?
Is this possible? The application I'm implementing this in is pretty restrictive, so I can't use any libraries, just pure JS.
Edit
I've changed the code to the below, which outputs an array of numbers on the encrypt, and accepts them as an input on the decrypt
function jEncryptDecrypt(data,key) {
let jKey = ''
let bytKey = [];
let bytData = [];
//expand key to cover length of input
for (let i = 1; i < (data.length/key.length) +1; i++) {
jKey = jKey + key;
}
//shorten key to same lenght as input
let str = jKey.substring(0, data.length);
//loop over key to create array of numbers from unicode value
for (let i = 0; i < str.length; ++i) {
var code = str.charCodeAt(i);
bytKey = bytKey.concat([code & 0xff, code / 256 >>> 0]);
}
//if data input is array no need to do anything
if (Array.isArray(data)) {
bytData = data;
//otherwise loop over data to create array of numbers from unicode value
} else {
let str2 = data
for (let i = 0; i < str2.length; ++i) {
var code = str2.charCodeAt(i);
bytData = bytData.concat([code & 0xff, code / 256 >>> 0]);
}
}
//XOR each data value with each key value in turn
for (let i = 0; i < bytData.length; ++i) {
bytData[i] = (bytData[i] ^ bytKey[i]);
}
//if input was array return string, otherwise return array
if (Array.isArray(data)) {
str3 = String.fromCharCode(...bytData)
str3 = str3.replace(/\0/g, '');
return str3;
} else {
return bytData;
}
}
It's clunky and hacky but works for my needs. If there is an answer to the original question that would still be much appreciated!