XOR 运算

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

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

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

XOR 加密原理

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

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

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

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

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

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

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

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

  1. function encryptByXOR(message, key) {
  2. let cipherText = "";
  3. for (let i = 0; i < message.length - 1; i++)
  4. cipherText += (message[i] ^ key).toString() + "-";
  5. cipherText += (message[message.length - 1] ^ key).toString();
  6. return cipherText;
  7. }
  8. function decryptByXOR(cipherText, key) {
  9. let message = "";
  10. cipherText = cipherText.split("-");
  11. for (let i = 0; i < cipherText.length; i++)
  12. message += String.fromCharCode(cipherText[i] ^ key);
  13. return message;
  14. }

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

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

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