一、XOR 运算

XOR 运算即 异或 运算,异或的定义是:两个值相同,返回false,否则返回 true,即 同假异真

JavaScript 中有一个专门的 XOR 运算符,写作 ^,使用它会将两个二进制数按位异或:

1
1010 ^ 1111	// 0101  注意这里的两个数都是二进制数

二、XOR 加密原理

XOR 运算有一个很奇妙的特点:如果对一个值连续做两次 XOR,会返回这个值本身:

1
2
3
4
5
// 第一次 XOR
1010 ^ 1111 // 0101

// 第二次 XOR
0101 ^ 1111 // 1010

XOR 的这个特性使得 XOR 运算可以用于信息的加密。

1
2
message ^ key	// 得到加密后的字符串 cipherText
cipherText ^ key // cipherText 与 key 再次进行 XOR 运算得到 message

加密得到的 cipherText 的长度与较长的那一方相同。

二战期间,各国为了电报加密,对密码学进行了大量的研究和实践,其中就包括 XOR 加密。战后,美国数学家香农(Claude Shannon)将他的研究成果公开发表,证明了只要满足两个条件,XOR 加密是无法破解的:

  • key的长度大于等于message
  • key必须是一次性的,且每次都要随机产生。

三、使用 XOR 加密字符串的简单实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function encryptByXOR(message, key) {
let cipherText = "";

for (let i = 0; i < message.length - 1; i++)
cipherText += (message[i] ^ key).toString() + "-";
cipherText += (message[message.length - 1] ^ key).toString();

return cipherText;
}

function decryptByXOR(cipherText, key) {
let message = "";
cipherText = cipherText.split("-");

for (let i = 0; i < cipherText.length; i++)
message += String.fromCharCode(cipherText[i] ^ key);

return message;
}

这里我实现了两个函数,encryptByXOR 用于加密,decryptByXOR 用于解密,它们的参数都是 messagekey

加密时,每个字符都与 key 异或,并以 - 为分隔符将所有结果拼接在一起,这样就产生了 cipherText

解密时,将cipherTextsplit 方法拆分,产生一个数组,然后循环遍历该数组,将数组中每个元素与 key 异或,并使用 String.fromCharCode 方法还原成字符,最后拼接并返回。