如何反转 Javascript XOR 和 AND 按位运算符

How to reverse Javascript XOR and AND bitwise Operators

我在 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+?)'));

控制台输出为:Microsoft Internet Explorer

是否可以反转一个函数来做相反的事情?

当我写的时候:

console.log(test('Microsoft Internet Explorer'));

我需要:@\f+ 6*5(.=j\x02"9+=>4&s\x11-&;7+?)

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;
}

-这里:

t += String.fromCharCode(e.charCodeAt(i) ^ i - n & 127);
                                             ^

位&运算不可逆:

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

您的代码使用第一个字符代码对其他字符代码进行异或。所以你不能简单地反转它,因为它需要 2 个输入。不仅是内容字符串,还有用于异或运算的字符。您无法猜测这是 @,因为所有字符都有效,但会产生不同的加密字符串。

XOR 是它自己的反面,类似于与 -1 相乘是它自己的反面。这意味着您可以重复使用单个函数进行加密和解密。剩下要做的就是在前面加上密钥字符加密,去掉它解密。

这不是代码高尔夫,所以我选择了一些更合理的名称(主要是 etn 令人困惑)。在我看来好的变量名可以帮助读者更好地理解代码。

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.

重要的是要注意 operator precedence 的:

code ^ index + 1 + keyCode & 127
// is executed as:
code ^ ((index + 1 + keyCode) & 127)

这意味着只有 XOR 运算符被调用 code,这是唯一需要反转的东西。