I have the code for a decryption algorithm but I'm struggling to figure out how to reverse it into the original encryption code.
function write(x) {
return x >= "0" && "9" >= x ? (x.charCodeAt(0) - 48) : (x >= "a") && "f" >= x ? (x.charCodeAt(0) - 87) : 0;
}
function ondata(input) {
var DATA = "";
var i = 0;
for (; i < input.length; i += 2) {
var diff = write(input[i]);
var firstNum = write(input[i + 1]);
val = 16 * diff + firstNum ^ [31, 126, 188, 168, 210, 3, 208, 219, 229, 149, 187, 222, 17, 31, 59, 100, 131, 62, 163, 81, 115, 154, 2, 220, 166, 30, 112, 192, 48, 172, 174, 119, 249, 5, 251, 41, 46, 148, 43, 210, 35, 42, 231, 145, 16, 6, 10, 28, 228, 49, 103, 248, 151, 109, 19, 20, 151, 243, 12, 193, 152, 126, 83, 235, 27, 109, 66, 96, 179, 88, 11, 189, 30, 187, 23, 172, 93, 109, 239, 247, 123, 105, 55, 98, 117, 175, 114, 212, 146, 136, 38, 115, 124, 39][i / 2];
DATA += String.fromCharCode(val);
}
return DATA;
}
ondata("6c0adddaa66abebc"); // 'starting' (javascript)
As shown, the string 6c0adddaa66abebc
produces the output starting
. My initial thought was to take the character code of each input character, but I wasn't sure what do to then. I'm sure it's just simple algebra but an explanation or a point in the right direction would be great, I'd like to learn from this.
UPDATE:
Ilmari Karonen's post gave me the help I needed to understand this. The problem I had was that I didn't actually understand what the long val = 16 * ...
line was doing. His refactored code and explanation helped me to understand the process. Here's how I came up with the solution if anybody's interested in the thought process:
I knew I had to reverse the function, like in algebra. So logically, I started with finding the character code of each letter in the starting string:
var x = value.charCodeAt(i);
Now, I had to "undo" the xor applied, which obviously (not to me) was just the xor function with the same key:
x ^= key[i];
Then, I had to undo the conversion of the hex string to a decimal number, which was just converting the decimal to a hex number:
var hex = x.toString(16);
I also had to add padded zero's to the hex number, because the decoder worked in pairs of two.
if (hex.length < 2) hex = '0' + hex;
Final solution:
function parse(value)
{
var result = "";
for (var i = 0; i < value.length; i++)
{
var x = value.charCodeAt(i);
x ^= key[i];
var hex = x.toString(16);
if(hex.length < 2)
hex = '0' + hex;
result += hex;
}
return result;
}