简单位运算加解密实现
soapgu opened this issue · comments
soapgu commented
-
按位取反加密
这是一个最简单的加解密方式,直接再执行相同操作就可以恢复原文,非常简单。
代码里面是执行~操作符即可。我们看一下代码原理
byte_value = b'a' # 这是一个ASCII码对应'a'字符的字节对象
print(byte_value[0])
# 提取第一个(也是唯一一个)字节,并进行按位取反
inv_byte = ~byte_value[0]
print(inv_byte)
执行结果为97和-98
学过ASCII编码的都知道,97就是a的编码,但是求反后-98是什么鬼,其实这是用补码的形式来表示
我们用二进制来表达下再看看
97 : 0110 0001
-98 : 1001 1110
是不是有感觉了。问题是我如果要操作文件内容的加密,就必须转为无符号整型,就是8位二进制。所以转为0~255范围数据。
代码如下
byte_value = b'a' # 这是一个ASCII码对应'a'字符的字节对象
def bitwise_not_encrypt( input : int ):
print(f"input byte:{input}")
output = ~input & 0xFF
# Python内部自动处理了符号扩展,因此得到的结果仍是在0-255之间的数字
# 由于Python内建的int类型是足够大的,它能存储任何这样的小整数而无需担心溢出问题
print(f"output byte:{output}")
return output
# 提取第一个(也是唯一一个)字节,并进行按位取反
print("encrypt>>>>>>>")
encrypt = bitwise_not_encrypt(byte_value[0])
print("decrypt>>>>>>>")
decrypt = bitwise_not_encrypt(encrypt)
文件操作相关代码
from Crypto.Random import get_random_bytes
import binascii
import os
import argparse
import time
parser = argparse.ArgumentParser(description='Process some files.')
parser.add_argument('-f', '--input-file', required=True, help='The input file')
args = parser.parse_args()
print(f"Input file: {args.input_file}")
ENCRYPT_SIZE = 1024
BLOCK_SIZE = 16 * 1024
download_path = args.input_file
output_filename = f"encrypt_{args.input_file}"
#print(f"key lenght:{len(binascii.unhexlify(keys))}")
in_file_length = os.path.getsize(download_path)
block_count = in_file_length / BLOCK_SIZE
print(in_file_length)
start_time = time.time()
count = 0
with open(download_path, 'rb') as in_file:
with open(output_filename, 'wb') as out_file:
# 1. write mess 1k data first
out_file.write( get_random_bytes(1024) )
# 2. read 1k data
head = in_file.read(ENCRYPT_SIZE)
# 3. aes encrypt and write
#hex_string = binascii.hexlify(head).decode()
#print(f"head content:{hex_string}")
crypted_chunk = bytes([~byte & 0xFF for byte in head])
out_file.write(crypted_chunk)
# 4. copy other part file
head_time = time.time() - start_time
print(f"加密头时间: {head_time} 秒")
while content := in_file.read(BLOCK_SIZE):
out_file.write(content)
out_file_length = os.path.getsize(output_filename)
print(f"encrypt ok,size {out_file_length}")
end_time = time.time()
run_time = end_time - start_time
print(f"按位取反加密运行时间: {run_time} 秒")
解密过程是完全对称的,这里就略过
其中有个计算机概念非常重要就是补码,还是有必要好好了解一下的
-
异或加密
-
什么是异或?
0 ^ 0 = 0
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
- 异或的特性
异或运算法则具有自反性、交换性和互补性
A ^ 0 = A
A ^ A = 0
(A ^ B) ^ C = A ^ (B ^ C)
(B ^ A) ^ A = B ^ 0 = B
- 加解密算法
from itertools import cycle
def xor_cipher(text, key):
encrypted_text = bytes([(c^k) for c, k in zip(text, cycle(key))])
return encrypted_text
def xor_decipher(encrypted_text, key):
# 加密和解密使用的是同一函数,因为异或运算具有相反可逆性
return xor_cipher(encrypted_text, key)
plaintext = b"Hello, World!"
key = b'shgbit'
encrypted = xor_cipher(plaintext, key)
print("Encrypted Text:", encrypted)
decrypted = xor_decipher(encrypted, key)
print("Decrypted Text:", decrypted)
-
文件替换方式加解密
对于大文件的加解密,文件的复制是一个很大的负担,如果我们只是部分加密可以使用快速替换的方式
但是需要满足下面条件
- 加密前后文件大小不变
- 对称加解密
同时文件还有一个模式读写模式来实现操作
from itertools import cycle
import os
import argparse
import time
def xor_cipher(text, key):
#encrypted_text = ''.join(chr(ord(c) ^ ord(k)) for c, k in zip(text, cycle(key)))
encrypted_text = bytes([(c^k) for c, k in zip(text, cycle(key))])
return encrypted_text
parser = argparse.ArgumentParser(description='Process some files.')
parser.add_argument('-f', '--input-file', required=True, help='The input file')
args = parser.parse_args()
print(f"Input file: {args.input_file}")
ENCRYPT_SIZE = 1024
download_path = args.input_file
#print(f"key lenght:{len(binascii.unhexlify(keys))}")
in_file_length = os.path.getsize(download_path)
print(in_file_length)
start_time = time.time()
count = 0
with open(download_path, 'rb') as in_file:
# read 1k data
head = in_file.read(ENCRYPT_SIZE)
# aes encrypt and write
crypted_chunk = xor_cipher(head,b"shgbit")
with open(download_path, 'r+b') as out_file:
out_file.seek(0)
out_file.write(crypted_chunk)
end_time = time.time()
run_time = end_time - start_time
print(f"按位异或加(解)密运行时间: {run_time} 秒")
看运行结果
guhui@guhuideMacBook-Pro RsaDemo % python3 xor_quick_encrypt.py -f film.mkv
Input file: film.mkv
16342579412
按位异或加(解)密运行时间: 0.00012111663818359375 秒
guhui@guhuideMacBook-Pro RsaDemo % python3 xor_quick_encrypt.py -f film.mkv
Input file: film.mkv
16342579412
按位异或加(解)密运行时间: 0.00012183189392089844 秒
16G的电影文件也是秒编秒解
相关文件模式参考