上次与异或(XOR)
见面已经是2023年,那个时候只是应对408
对它进行了了解和学习。
是时候学习一下异或(XOR)
了!
异或(XOR)
异或是一个运算方法,在计算机领域可以理解成跟耳熟能详的加减乘除一样,用于计算的。但是它一个二进制
运算符,是根据二进制位
来计算结果的。核心的计算规则就一句话:
IMPORTANT位相同异或为0,不同为1
打个比方,a = 5
,b = 3
,它们的二进制分别为:a = 0101
,b = 0011
,对他们进行异或运算可以得到结果:
0101
^ 0011
------
0110
计算结果为0110
,也就是10进制数字6。曾经在学习计算机组成原理的时候,了解到它经常被在逻辑控制单元里面担当一些异或门
来对信号进行控制的,但是原理都是对信号进行异或计算来达到控制的目的的。
异或加密
为什么会去了解到异或加密
呢?其实是在考虑博客前端加密而了解到的。参考了一些博客框架的加密方法,都是在博客的frontmatter
里面加一个密码字段,将明文的文章进行加密使之成为密文,这样密码和文章就不会暴露在前端页面中,加密过程中使用的KEY
就是密码字段。而对明文的加密方法通常就使用的是异或加密。
通常使用的加密方法是对称加密
,也就是说加密和解密使用的是同一个KEY
,在构建时就会使用KEY
将文章加密成密文,在前端页面中,通过用户输入的密码直接进行解密,不需要进行密码的校验,因为如果输入的密码与KEY
一致会成功解密得到明文,否则解密失败。
这样就可以很好的保护文章的隐私,防止文章被泄露。同时也不需要后端进行密码校验,而且密码也不会暴露在前端。
文章内容的加密和解密
根据我的资料查询,有很多种异或加密方式,但是基本都涉及到一个核心: 将文章内容分块,每一块内容都跟KEY
进行异或计算得到密文,解密也是一样的,将密文块逐个跟KEY
进行异或计算即可解密,所以这个过程一般来讲是由顺序的,否则解密成功组成明文也会乱序。
一个字符一个字符的异或运算也是完全可以,生成文本每个字符的Unicode
码列表,同样的KEY
也需要生成Unicode
码列表,然后遍历文本的列表,逐个与KEY
列表遍历,打个比方:
def xor_encrypt(text, key):
# 明文转ASCII码索引列表
text_ = [ord(char) for char in text]
# KEY转ASCII码索引列表
key_ = [ord(char) for char in key]
encrypted = []
for i in range(len(text_)):
# 逐个异或后转成ASCII索引对应的字符
encrypted.append(chr(text_[i] ^ key_[i % len(key_)]))
return ''.join(encrypted)
调用上面的函数
print(xor_encrypt("hello world", "123456"))
# 输出
"YW_XZF]AXQ"
这样就加密完成了,解密也一样,将密文块逐个跟KEY
进行异或计算即可解密。同样打个比方:
def xor_decrypt(text, key):
# 密文转ASCII码索引列表
text_ = [ord(char) for char in text]
# KEY转ASCII码索引列表
key_ = [ord(char) for char in key]
decrypted = []
for i in range(len(text_)):
# 逐个异或后转成ASCII索引对应的字符
decrypted.append(chr(text_[i] ^ key_[i % len(key_)]))
return ''.join(decrypted)
# 用上面的密文作为输入
print(xor_decrypt("YW_XZF]AXQ", "123456"))
# 输出
"hello world"
# 如果输入的密码不正确
print(xor_decrypt("YW_XZF]AXQ", "34556"))
# 输出
"jcjml%rhtnb"
加密和解密的目的就达成了