简体   繁体   中英

How to reverse Javascript XOR and AND bitwise Operators

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+?)

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.

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);
                                             ^

Bitwise & operation cannot be reversed:

0 & 1 = 0; 
0 & 0 = 0;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM