XOR 运算
XOR 运算即 异或 运算,异或的定义是:两个值相同,返回false
,否则返回 true
,即 同假异真。
JavaScript 中有一个专门的 XOR 运算符,写作 ^
,使用它会将两个二进制数按位异或:
1010 ^ 1111 // 0101 注意这里的两个数都是二进制数
XOR 加密原理
XOR 运算有一个很奇妙的特点:如果对一个值连续做两次 XOR,会返回这个值本身:
// 第一次 XOR
1010 ^ 1111 // 0101
// 第二次 XOR
0101 ^ 1111 // 1010
XOR 的这个特性使得 XOR 运算可以用于信息的加密:
message ^ key // 得到加密后的字符串 cipherText
cipherText ^ key // cipherText 与 key 再次进行 XOR 运算得到 message
加密得到的 cipherText
的长度与较长的那一方相同。
二战期间,各国为了电报加密,对密码学进行了大量的研究和实践,其中就包括 XOR 加密。战后,美国数学家香农(Claude Shannon)将他的研究成果公开发表,证明了只要满足两个条件,XOR 加密是无法破解的:
key
的长度大于等于message
。key
必须是一次性的,且每次都要随机产生。
使用 XOR 加密字符串的简单实例
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
用于解密,它们的参数都是 message
和 key
。
加密时,每个字符都与 key
异或,并以 -
为分隔符将所有结果拼接在一起,这样就产生了 cipherText
。
解密时,将cipherText
用 split
方法拆分,产生一个数组,然后循环遍历该数组,将数组中每个元素与 key
异或,并使用 String.fromCharCode
方法还原成字符,最后拼接并返回。