python加密word文档
我们先了解一下异或是什么。简单来说,如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。我们简单的梳理一下代码思路。代码分为两部分,加密和解密。
1.加密
把文件转换成二进制的格式,然后生成等长的随机密钥进行异或操作,得到加密后的二进制文件。这一步我们需要保留的数据有,加密后的文件和随机生成的密钥,当然他们都是一些二进制数。
2.解密
这一步就简单了,我们把加密后的文件和之前随机生成的密钥再进行一次异或操作,即可得到原本的二进制数,然后我们再把它转换成文本即可。
ok,思路大致明了了,我们需要两个程序,加密程序接收str参数 ,运行完成会输出加密后的二进制word文档,和用于解密的二进制密钥。解密程序则需要接收两个int参数,分别为加密程序输出的两个二进制内容,异或之后输出原始文本。那么,上代码。
加密代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
from secrets import token_bytes
from docx import document
import docx
import time
def random_key(length):
# token_bytes,函数接受一个int参数,用于指定随机字节串的长度。
# int.from_bytes把字节串转换为int,也就是我们需要的二进制数
key = token_bytes(nbytes = length)
key_int = int .from_bytes(key, 'big' )
return key_int
def encrypt(raw):
raw_bytes = raw.encode()
#参数big意为正序,little则输出反序。
raw_int = int .from_bytes(raw_bytes, 'big' )
key_int = random_key( len (raw_bytes))
return raw_int ^ key_int, key_int
def decrypt(encrypted, key_int):
decrypted = encrypted ^ key_int
length = (decrypted.bit_length() + 7 ) / / 8
decrypted_bytes = int .to_bytes(decrypted, length, 'big' )
return decrypted_bytes.decode()
def encrypt_file(path, key_path = none,):
document = document(path)
all_paragraphs = document.paragraphs
file = docx.document()
file2 = docx.document()
jkl = input ( '请输入希望保存的文件名:' ) + '.docx'
for paragraph in all_paragraphs:
# 打印每一个段落的文字
zz,key = encrypt(paragraph.text)
#print('加密:',zz)
#print('key:', key)
file .add_paragraph( str (zz))
file .save(jkl)
file2.add_paragraph( str (key))
file2.save( "key.docx" )
print ( '滑稽研究所出品!' )
print ( '仅支持英文文件名。' )
chenggong = encrypt_file( input ( '请输入需要加密的文件名:' ))
print ( "已完成!十秒后自动关闭" )
time.sleep( 10 )
#生成加密文件
|
通过 encode 方法,将字符串编码成字节串。int.from_bytes 函数将字节串转换为 int 对象。最后对二进制对象和随机密钥进行异或操作,就得到了加密文本。
解密代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
from secrets import token_bytes
from docx import document
import docx
import time
def random_key(length):
# token_bytes,函数接受一个int参数,用于指定随机字节串的长度。
# int.from_bytes把字节串转换为int,也就是我们需要的二进制数
key = token_bytes(nbytes = length)
key_int = int .from_bytes(key, 'big' )
return key_int
def encrypt(raw):
raw_bytes = raw.encode()
raw_int = int .from_bytes(raw_bytes, 'big' )
key_int = random_key( len (raw_bytes))
return raw_int ^ key_int, key_int
def decrypt(encrypted, key_int):
decrypted = encrypted ^ key_int
length = (decrypted.bit_length() + 7 ) / / 8
decrypted_bytes = int .to_bytes(decrypted, length, 'big' )
return decrypted_bytes.decode()
jjj = []
kkk = []
def decrypt_file(path_encrypted, key_path = none, * , encoding = 'utf-8' ):
document = document(path_encrypted)
all_paragraphs = document.paragraphs
do2 = document( 'key.docx' )
all_p = do2.paragraphs
for i in all_paragraphs:
#str转int
jiam = int (i.text)
jjj.append(jiam)
#print('加密:',jiam)
#print(jjj)
for k in all_p:
#str转int
key = int (k.text)
kkk.append(key)
#print('key:',key)
#print(kkk)
cc = zip (jjj,kkk)
res = list (cc)
return res
#传入元组,或两个int。
print ( '滑稽研究所出品!' )
print ( '警告,严禁修改密钥文件名!!!' )
print ( '直接输入文件名,无需格式后缀。' )
rr1 = decrypt_file( input ( "请输入需要破解文件的文件名(仅限.docx文件):" ) + '.docx' )
file = docx.document()
for i in rr1:
ff = decrypt( * i)
#print(ff)
#print(type(ff))
file .add_paragraph(ff)
file .save( "res.docx" )
print ( '解密完成,请在当前文件夹下提取文件!' )
print ( '十秒后自动关闭!' )
time.sleep( 10 )
|
我们需要将两个程序打包成exe。运行加密程序得到的二进制word文档,可以给其他人,但密钥必须自己保存。当别人满足你的要求之后,我们可以把密钥和解密程序给他。注意,只对docx文件有效,且不可以修改密钥文件的名称,不然会报错,解密失败。
运行结果:
原始word文件。
加密后:
生成的key密钥:
加密后的文件和生成的密钥,放在解密程序文件夹下之后,会得到如下。我们得到了原文件,美中不足的是所有的首行缩进都消失了,变成了左对齐。
同样的文件,重新加密之后,会得到不同的加密文件和密钥。因此如果加密文件和密钥不匹配,即使他们的源文件是一样的,也是无法解密的。此外密钥丢失,加密的文件将永远不能解密。
总结
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注服务器之家的更多内容!
原文链接:https://blog.csdn.net/weixin_45067072/article/details/119717751