如何反转 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
相乘是它自己的反面。这意味着您可以重复使用单个函数进行加密和解密。剩下要做的就是在前面加上密钥字符加密,去掉它解密。
这不是代码高尔夫,所以我选择了一些更合理的名称(主要是 e
、t
和 n
令人困惑)。在我看来好的变量名可以帮助读者更好地理解代码。
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
,这是唯一需要反转的东西。
我在 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
相乘是它自己的反面。这意味着您可以重复使用单个函数进行加密和解密。剩下要做的就是在前面加上密钥字符加密,去掉它解密。
这不是代码高尔夫,所以我选择了一些更合理的名称(主要是 e
、t
和 n
令人困惑)。在我看来好的变量名可以帮助读者更好地理解代码。
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
,这是唯一需要反转的东西。