在当前h5各种活动漫天轰炸的时代,大量的访问量给h5带来了机遇,同时也带来了一些安全隐患,如何能对数据进行一些合理的加密成了我们H5必须考虑的问题,今天就先写下异或
一、 XOR 运算
逻辑运算之中,除了
AND
和
OR
,还有一种
XOR
运算,中文称为"异或运算"。
它的定义是:两个值相同时,返回
false
,否则返回
true
。也就是说,
XOR
可以用来判断两个值是否不同。
上面代码中,如果两个二进制位相同,就返回
0
,表示
false
;否则返回
1
,表示
true
。
二、 XOR 的应用
XOR 运算有一个很奇妙的特点:如果对一个值连续做两次 XOR,会返回这个值本身。
// 第一次 XOR 1010 ^ 1111 // 0101 // 第二次 XOR 0101 ^ 1111 // 1010
上面代码中,原始值是
1010
,再任意选择一个值(上例是
1111
),做两次 XOR,最后总是会得到原始值
1010
。这在数学上是很容易证明的。
三、加密应用
XOR 的这个特点,使得它可以用于信息的加密。
message XOR key // cipherText cipherText XOR key // message
上面代码中,原始信息是
message
,密钥是
key
,第一次 XOR 会得到加密文本
cipherText
。对方拿到以后,再用
key
做一次 XOR 运算,就会还原得到
message
。
理由很简单,如果每次的
key
都是随机的,那么产生的
CipherText
具有所有可能的值,而且是均匀分布,无法从
CipherText
看出
message
的任何特征。也就是说,它具有最大的"信息熵",因此完全不可能破解。这被称为 XOR 的
"完美保密性"
(perfect secrecy)。
满足上面两个条件的
key
,叫做
one-time pad
(缩写为OTP),意思是"一次性密码本",因为以前这样的
key
都是印刷成密码本,每次使用的时候,必须从其中挑选
key
。
五、实例:哈希加密
下面的例子使用 XOR,对用户的登陆密码进行加密。实际运行效果看 这里 。
// 生成一个随机整数,范围是 [min, max] function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; // 生成一个随机的十六进制的值,在 0 ~ f 之间 function getHex() { let n = 0; for (let i = 4; i > 0; i--) { n = (getRandomInt(0, 1) << (i - 1)) + n; return n.toString(16); // 生成一个32位的十六进制值,用作一次性 Key function getOTP() { const arr = []; for (let i = 0; i < 32; i++) { arr.push(getHex()); return arr.join('');
上面代码中,生成的
key
是32位的十六进制值,对应 MD5 产生的128位的二进制哈希。
第三步,进行 XOR 运算,求出加密后的
message
。
使用这种方法保存用户的登陆密码,即使加密文本泄露,只要一次性的密钥(
key
)没有泄露,对方也无法破解。
典型XOR解密及unicode转义汉字
// 异或解密(异或加密相当于一个双重加密,双重保障更安全)
export function Restore(str, keyIndex)
var crytxt = '';
var k, keylen = keyIndex.length;
for(var i=0; i<str.length; i++) {
k = i % keylen;
crytxt += String.fromCharCode(str.charCodeAt(i) ^ keyIndex.charCodeAt(k));
return toChineseWords(crytxt);
export function toChineseWords(data){
var str= unescape(data.replace(/\\/g, "%"));