用Python进行XOR加解密


=Start=

缘由:

简单记录一下 XOR 操作(包括加解密)和用Python进行XOR加解密的方法,方便后面有需要的时候参考。

正文:

参考解答:

异或运算的含义和运算定律

XOR 主要用来判断两个值是否不同。

XOR 一般使用插入符号(caret)^表示。如果约定0 为 false,1 为 true,那么 XOR 的运算真值表如下。

0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

XOR 运算有以下的运算定律。

(1)一个值与自身的运算,总是为 false。

x ^ x = 0

(2)一个值与 0 的运算,总是等于其本身。

x ^ 0 = x

(3)可交换性

x ^ y = y ^ x

(4)结合性

x ^ (y ^ z) = (x ^ y) ^ z

根据上面的这些运算定律,可以得到异或运算的很多重要应用。

  1. 简化计算

多个值的异或运算,可以根据运算定律进行简化。

a ^ b ^ c ^ a ^ b
= a ^ a ^ b ^ b ^ c
= 0 ^ 0 ^ c
= c

  1. 交换值

两个变量连续进行三次异或运算,可以互相交换值。

假设两个变量是x和y,各自的值是a和b。下面就是x和y进行三次异或运算,注释部分是每次运算后两个变量的值。

x = x ^ y // (a ^ b, b)
y = x ^ y // (a ^ b, a ^ b ^ b) => (a ^ b, a)
x = x ^ y // (a ^ b ^ a, a) => (b, a)

这是两个变量交换值的最快方法,不需要任何额外的空间。

  1. 加密

异或运算可以用于加密。

第一步,明文(text)与密钥(key)进行异或运算,可以得到密文(cipherText)。

text ^ key = cipherText

第二步,密文与密钥再次进行异或运算,就可以还原成明文。

cipherText ^ key = text

原理很简单,如果明文是 x,密钥是 y,那么 x 连续与 y 进行两次异或运算,得到自身。

(x ^ y) ^ y
= x ^ (y ^ y)
= x ^ 0
= x

  1. 数据备份

异或运算可以用于数据备份。

文件 x 和文件 y 进行异或运算,产生一个备份文件 z。

x ^ y = z

以后,无论是文件 x 或文件 y 损坏,只要不是两个原始文件同时损坏,就能根据另一个文件和备份文件,进行还原。

x ^ z
= x ^ (x ^ y)
= (x ^ x) ^ y
= 0 ^ y
= y

上面的例子是 y 损坏,x 和 z 进行异或运算,就能得到 y。

用Python 3进行异或运算

在Python 3中对一段 message 字符串用指定的 key 字符串进行 XOR 加密

#!/usr/bin/env python3

from itertools import cycle

cryptedMessage = ''.join(chr(ord(c)^ord(k)) for c,k in zip(message, cycle(key)))

简单封装的一段代码

#!/usr/bin/env python3
# coding=utf-8

from itertools import cycle

def xor_str(msg, key):
    return ''.join(chr( ord(c)^ord(k) ) for c,k in zip(msg, cycle(key)))

def xor_file(input_file_path, output_file_path, key):
    input_data = ''
    with open(input_file_path) as fp:
        input_data = fp.read()
        print('file:{0}, char \\n count = {1}'.format(input_file_path, input_data.count('\n')))

    output_data = xor_str(input_data, key)
    # 下面以默认的字符串形式写入文件时,XOR加密之后的文件内容大概率是乱码的形式,可以考虑在写入之前先 base64 编码处理一下
    # 然后上面读取的时候再 base64 解码处理就好
    with open(output_file_path, 'w') as fp:
        fp.write(output_data)

def encrypt_decrypt_xor():
    raw_file_path = 'raw_data.txt'
    key_str = 'password_here'

    xor_encrypt_file_path = 'data_xor_encrypt.txt'
    xor_decrypt_file_path = 'data_xor_decrypt.txt'

    # 对于 XOR 算法来说,加密和解密是相同的操作,密钥也相同
    xor_file(raw_file_path, xor_encrypt_file_path, key_str) #对原始文件用密钥进行XOR加密生成加密文件
    xor_file(xor_encrypt_file_path, xor_decrypt_file_path, key_str) #对加密文件用密钥进行XOR解密生成解密文件

    with open(raw_file_path) as fp1, open(xor_decrypt_file_path) as fp2:
        raw_data = fp1.read()
        decrypt_data = fp2.read()
        print('xor decrypt data compare raw data: {0}'.format('equal' if raw_data == decrypt_data else 'not equal')) #对比一下原始数据和解密之后数据内容是否相等
#encrypt_decrypt_xor
参考链接:

异或运算 XOR 教程
https://mp.weixin.qq.com/s/dVOyUMaJRRIsND0yz4Llvg
https://www.ruanyifeng.com/blog/2021/01/_xor.html

如何理解「异或(XOR)」运算在计算机科学中的重要性?
https://www.zhihu.com/question/20484426

如何理解「异或」的含义?
https://www.zhihu.com/question/31116687

XOR 加密简介
https://www.ruanyifeng.com/blog/2017/05/xor.html

XOR Python Text Encryption/Decryption
https://stackoverflow.com/questions/20557999/xor-python-text-encryption-decryption
https://stackoverflow.com/questions/20557999/xor-python-text-encryption-decryption/65436166#65436166

XOR cipher
https://en.wikipedia.org/wiki/XOR_cipher

Simple python XOR encrypt/decrypt
https://gist.github.com/nawie/028c85e29503a5e2d8de106ebd972017

=END=


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注