Reputation: 33
I have this code in JS:
function test(e) {
for (var t = "", n = e.charCodeAt(0), i = 1; i < e.length; ++i) {
t += String.fromCharCode(e.charCodeAt(i) ^ i + n & 127);
}
return t;
}
console.log(test('@\f+ 6*5(.=j\x02"9+=>4&s\x11-&;7+?)'));
Console Output is: Microsoft Internet Explorer
Is it possible to reverse a function to do the opposite?
When I write:
console.log(test('Microsoft Internet Explorer'));
I need: @\f+ 6*5(.=j\x02"9+=>4&s\x11-&;7+?)
Upvotes: 0
Views: 1097
Reputation: 21130
Your code uses the first character code to XOR the other characters codes. So you can't simply reverse it since it expects 2 inputs. Not just the content string, but also the character that is used for the XOR operation. You can't guess this to be the @
since all characters are valid, but produce different encrypted stings.
XOR is the reverse of itself, similar to how multiplying with -1
is the reverse of itself. This means you can re-use a single function for encryption and decryption. The only thing left to do is add the key character at the front for encryption, and remove it for decryption.
This is not code golf, so I've chose some more sensible names (mainly e
, t
and n
are confusing). In my opinion good variable names help readers understand the code better.
function toggleEncryption(keyChar, string) {
const keyCode = keyChar.charCodeAt(0);
let result = "";
for (let index = 0; index < string.length; ++index) {
const code = string.charCodeAt(index);
result += String.fromCharCode(code ^ index + 1 + keyCode & 127);
}
return result;
}
function decrypt(encryptedString) {
return toggleEncryption(encryptedString[0], encryptedString.slice(1));
}
function encrypt(keyChar, string) {
return keyChar[0] + toggleEncryption(keyChar, string);
}
const string = "Microsoft Internet Explorer";
console.log(string);
const encrypted = encrypt("@", string);
console.log(encrypted);
const decrypted = decrypt(encrypted);
console.log(decrypted);
console.log(string == decrypted);
console.log(encrypted == '@\f+ 6*5(.=j\x02"9+=>4&s\x11-&;7+?)');
// Like I said in the introduction you could replace the @ with
// any character, but this will produce a different encrypted
// string.
const encrypted2 = encrypt("!", string);
console.log(encrypted2);
const decrypted2 = decrypt(encrypted2);
console.log(decrypted2);
Non-printable characters are not displayed inside the Stack Overflow snippet, but most browsers do show them in the browser console. For most browsers press Ctrl + Shift + I or F12 to open up developer tools and select the console.
It's important to note the operator precedence of:
code ^ index + 1 + keyCode & 127
// is executed as:
code ^ ((index + 1 + keyCode) & 127)
This means that only the XOR operator is called upon code
and that is the only thing that has to be reversed.
Upvotes: 1
Reputation: 124
Bitwise & operation cannot be reversed :
0 & 1 = 0;
0 & 0 = 0;
Upvotes: 0
Reputation: 131
function test(e) {
for (var t = "", n = e.charCodeAt(0), i = 1; i < e.length; ++i) {
t += String.fromCharCode(e.charCodeAt(i) ^ i - n & 127);
}
return t;
}
Look at -
here:
t += String.fromCharCode(e.charCodeAt(i) ^ i - n & 127);
^
Upvotes: 0