Python加密解密与调试全解析
1. 列表插入方法insert()
在Python中,
insert()
方法可用于在列表的指定索引位置插入值。以下是一个示例:
>>> spam = [2, 4, 6, 8]
>>> spam.insert(0, 'hello')
>>> spam
['hello', 2, 4, 6, 8]
>>> spam.insert(2, 'world')
>>> spam
['hello', 2, 'world', 4, 6, 8]
在这个例子中,我们先创建了一个列表
spam
,然后在索引0处插入字符串
'hello'
,还可以在其他现有索引位置插入值,如索引2处。
2. 合并消息列表为字符串
可以使用
SYMBOLS
字符串将
charIndex
中的符号集索引转换为对应的字符,并将该字符插入到列表的索引0位置。示例代码如下:
blockMessage.insert(0, SYMBOLS[charIndex])
message.extend(blockMessage)
return ''.join(message)
通过这种方式,可以将消息列表合并为一个字符串。
3. 编写加密函数
encryptMessage()
encryptMessage()
函数用于加密消息。它接受消息字符串、公钥(一个由两个整数组成的元组)和块大小作为参数,并返回一个加密块的列表。以下是该函数的代码:
def encryptMessage(message, key, blockSize):
# Converts the message string into a list of block integers, and then
# encrypts each block integer. Pass the PUBLIC key to encrypt.
encryptedBlocks = []
n, e = key
for block in getBlocksFromText(message, blockSize):
# ciphertext = plaintext ^ e mod n
encryptedBlocks.append(pow(block, e, n))
return encryptedBlocks
在这个函数中,首先创建一个空列表
encryptedBlocks
来存储加密块。然后将公钥的两个整数分别赋值给
n
和
e
。接着,对消息的每个块进行加密操作,将块的
e
次幂对
n
取模的结果添加到
encryptedBlocks
列表中。
4. 编写解密函数
decryptMessage()
decryptMessage()
函数用于解密加密块并返回解密后的消息字符串。它接受加密块列表、消息长度、私钥和块大小作为参数。以下是该函数的代码:
def decryptMessage(encryptedBlocks, messageLength, key, blockSize):
# Decrypts a list of encrypted block ints into the original message
# string. The original message length is required to properly decrypt
# the last block. Be sure to pass the PRIVATE key to decrypt.
decryptedBlocks = []
n, d = key
for block in encryptedBlocks:
# plaintext = ciphertext ^ d mod n
decryptedBlocks.append(pow(block, d, n))
return getTextFromBlocks(decryptedBlocks, messageLength, blockSize)
该函数的工作原理与加密函数类似,只是使用私钥的
d
值进行解密操作。
5. 从密钥文件中读取公钥和私钥
readKeyFile()
函数用于从密钥文件中读取公钥或私钥,并返回一个元组。以下是该函数的代码:
def readKeyFile(keyFilename):
# Given the filename of a file that contains a public or private key,
# return the key as a (n,e) or (n,d) tuple value.
fo = open(keyFilename)
content = fo.read()
fo.close()
keySize, n, EorD = content.split(',')
return (int(keySize), int(n), int(EorD))
该函数首先打开指定的密钥文件,读取其内容,然后使用逗号分割字符串,将分割后的字符串转换为整数,并返回一个包含三个整数的元组。
6. 将加密内容写入文件
encryptAndWriteToFile()
函数用于加密消息并将结果写入文件。它接受消息文件名、密钥文件名、消息和块大小作为参数。以下是该函数的代码:
def encryptAndWriteToFile(messageFilename, keyFilename, message, blockSize=None):
# Using a key from a key file, encrypt the message and save it to a
# file. Returns the encrypted message string.
keySize, n, e = readKeyFile(keyFilename)
if blockSize == None:
# If blockSize isn't given, set it to the largest size allowed by
# the key size and symbol set size.
blockSize = int(math.log(2 ** keySize, len(SYMBOLS)))
# Check that key size is large enough for the block size:
if not (math.log(2 ** keySize, len(SYMBOLS)) >= blockSize):
sys.exit('ERROR: Block size is too large for the key and symbol set size. Did you specify the correct key file and encrypted file?')
# Encrypt the message
encryptedBlocks = encryptMessage(message, (n, e), blockSize)
# Convert the large int values to one string value:
for i in range(len(encryptedBlocks)):
encryptedBlocks[i] = str(encryptedBlocks[i])
encryptedContent = ','.join(encryptedBlocks)
# Write out the encrypted string to the output file:
encryptedContent = '%s_%s_%s' % (len(message), blockSize, encryptedContent)
fo = open(messageFilename, 'w')
fo.write(encryptedContent)
fo.close()
# Also return the encrypted string:
return encryptedContent
该函数的操作步骤如下:
1. 调用
readKeyFile()
函数读取密钥文件中的
keySize
、
n
和
e
。
2. 如果没有指定块大小,则根据密钥大小和符号集大小计算最大块大小。
3. 检查密钥大小是否足够大,如果块大小太大,程序将退出并显示错误信息。
4. 调用
encryptMessage()
函数对消息进行加密,得到加密块列表。
5. 将加密块列表中的整数转换为字符串,并使用逗号连接成一个字符串。
6. 将消息长度、块大小和加密内容用下划线连接起来。
7. 打开指定的消息文件,将加密内容写入文件。
8. 关闭文件并返回加密字符串。
7. 从文件中读取并解密
readFromFileAndDecrypt()
函数用于从文件中读取加密消息并进行解密。它接受加密消息文件名和密钥文件名作为参数。以下是该函数的代码:
def readFromFileAndDecrypt(messageFilename, keyFilename):
# Using a key from a key file, read an encrypted message from a file
# and then decrypt it. Returns the decrypted message string.
keySize, n, d = readKeyFile(keyFilename)
# Read in the message length and the encrypted message from the file:
fo = open(messageFilename)
content = fo.read()
fo.close()
messageLength, blockSize, encryptedMessage = content.split('_')
messageLength = int(messageLength)
blockSize = int(blockSize)
# Check that key size is large enough for the block size:
if not (math.log(2 ** keySize, len(SYMBOLS)) >= blockSize):
sys.exit('ERROR: Block size is too large for the key and symbol set size. Did you specify the correct key file and encrypted file?')
# Convert the encrypted message into large int values:
encryptedBlocks = []
for block in encryptedMessage.split(','):
encryptedBlocks.append(int(block))
# Decrypt the large int values:
return decryptMessage(encryptedBlocks, messageLength, (n, d), blockSize)
该函数的操作步骤如下:
1. 调用
readKeyFile()
函数读取密钥文件中的
keySize
、
n
和
d
。
2. 打开加密消息文件,读取其内容。
3. 使用下划线分割内容,得到消息长度、块大小和加密消息。
4. 将消息长度和块大小转换为整数。
5. 检查密钥大小是否足够大,如果块大小太大,程序将退出并显示错误信息。
6. 将加密消息字符串按逗号分割,将每个块转换为整数并存储在
encryptedBlocks
列表中。
7. 调用
decryptMessage()
函数对加密块进行解密并返回解密后的消息字符串。
8. 调用主函数
最后,如果程序作为主程序运行,则调用
main()
函数:
if __name__ == '__main__':
main()
9. 调试Python代码
IDLE包含一个内置的调试器,它允许你逐行执行程序,是查找程序中错误的宝贵工具。以下是调试器的使用步骤:
1.
启用调试器
:在交互式shell窗口中,点击
Debug▸Debugger
,会出现
Debug Control
窗口。
2.
显示调试信息
:在
Debug Control
窗口中,选择
Stack
、
Locals
、
Source
和
Globals
复选框,以显示完整的调试信息。
3.
运行程序
:当
Debug Control
窗口可见时,从文件编辑器运行程序,调试器会在第一条指令之前暂停执行,并显示即将执行的代码行、所有局部变量及其值、所有全局变量及其值。
4.
操作按钮
:程序将保持暂停状态,直到你点击
Debug Control
窗口中的五个按钮之一:
-
Go
:正常执行程序,直到程序终止或到达断点。
-
Step
:执行下一行代码,执行后程序再次暂停。如果下一行是函数调用,调试器会进入该函数。
-
Over
:执行下一行代码,如果下一行是函数调用,会跳过函数内部代码,函数执行完毕后调试器暂停。
-
Out
:从当前函数中跳出,继续执行函数调用后的代码。
-
Quit
:退出调试模式。
以下是调试器操作的流程图:
graph TD;
A[启用调试器] --> B[显示调试信息];
B --> C[运行程序];
C --> D{选择操作按钮};
D -->|Go| E[正常执行到终止或断点];
D -->|Step| F[执行下一行并暂停];
D -->|Over| G[跳过函数内部执行];
D -->|Out| H[跳出当前函数];
D -->|Quit| I[退出调试模式];
总结
通过上述内容,我们学习了Python中列表的插入操作、消息的加密和解密、密钥文件的读取和写入,以及如何使用IDLE的调试器来查找程序中的错误。在实际应用中,虽然这里介绍的加密算法是真实的,但由于存在一些安全漏洞,不建议用于保护重要的秘密文件。同时,建议使用专业的加密软件来确保信息的安全。如果你想深入学习编程和密码学,可以参考相关书籍和网站,如《The Code Book: The Science of Secrecy from Ancient Egypt to Quantum Cryptography》,也可以通过电子邮件或论坛提问交流。
在加密和解密过程中,各函数的参数和功能总结如下表:
| 函数名 | 参数 | 功能 |
| ---- | ---- | ---- |
|
encryptMessage
|
message
,
key
,
blockSize
| 加密消息,返回加密块列表 |
|
decryptMessage
|
encryptedBlocks
,
messageLength
,
key
,
blockSize
| 解密加密块,返回解密后的消息字符串 |
|
readKeyFile
|
keyFilename
| 从密钥文件中读取密钥,返回元组 |
|
encryptAndWriteToFile
|
messageFilename
,
keyFilename
,
message
,
blockSize
| 加密消息并写入文件,返回加密字符串 |
|
readFromFileAndDecrypt
|
messageFilename
,
keyFilename
| 从文件中读取加密消息并解密,返回解密后的消息字符串 |
Python加密解密与调试全解析
10. 加密解密流程梳理
为了更清晰地理解整个加密和解密的过程,我们可以将其流程进行梳理。以下是加密和解密的主要步骤:
加密流程
:
1. 从密钥文件中读取公钥信息(
keySize
,
n
,
e
)。
2. 根据密钥大小和符号集大小确定块大小(若未指定)。
3. 检查密钥大小是否足够支持块大小。
4. 将消息转换为块整数列表。
5. 对每个块进行加密操作(
pow(block, e, n)
)。
6. 将加密块列表转换为字符串。
7. 拼接消息长度、块大小和加密字符串。
8. 将加密内容写入文件。
解密流程
:
1. 从密钥文件中读取私钥信息(
keySize
,
n
,
d
)。
2. 从加密文件中读取消息长度、块大小和加密消息。
3. 检查密钥大小是否足够支持块大小。
4. 将加密消息字符串转换为加密块整数列表。
5. 对每个加密块进行解密操作(
pow(block, d, n)
)。
6. 将解密块转换为原始消息字符串。
以下是加密和解密流程的mermaid格式流程图:
graph LR;
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始加密]):::startend --> B(读取公钥):::process;
B --> C{块大小是否指定}:::decision;
C -->|是| D(使用指定块大小):::process;
C -->|否| E(计算最大块大小):::process;
D --> F{密钥大小是否足够}:::decision;
E --> F;
F -->|是| G(消息转块整数列表):::process;
F -->|否| H(程序退出并报错):::process;
G --> I(加密每个块):::process;
I --> J(加密块转字符串):::process;
J --> K(拼接信息):::process;
K --> L(写入文件):::process;
L --> M([结束加密]):::startend;
N([开始解密]):::startend --> O(读取私钥):::process;
O --> P(读取加密文件内容):::process;
P --> Q(分割内容获取信息):::process;
Q --> R{密钥大小是否足够}:::decision;
R -->|是| S(加密消息转块整数列表):::process;
R -->|否| H;
S --> T(解密每个块):::process;
T --> U(解密块转原始消息):::process;
U --> V([结束解密]):::startend;
11. 注意事项与安全建议
在使用上述加密和解密方法时,有一些注意事项和安全建议需要牢记:
-
密钥管理
:
- 确保公钥和私钥文件的安全性,避免泄露。
- 定期更换密钥,以增加安全性。
-
块大小选择
:
- 块大小的选择要根据密钥大小和符号集大小合理确定,避免因块大小过大导致加密失败。
-
随机数问题
:
- 由于使用的随机数可能不是真正随机的,存在被预测的风险,因此不建议将此程序用于保护重要的秘密文件。
-
专业加密软件
:
- 对于重要的信息加密,建议使用专业的加密软件,这些软件经过了严格的测试和审查,安全性更高。
12. 进一步学习资源
如果你对编程和密码学感兴趣,想要深入学习,可以参考以下资源:
-
书籍
:《The Code Book: The Science of Secrecy from Ancient Egypt to Quantum Cryptography》,这本书介绍了从古代埃及到量子密码学的密码学历史。
-
网站
:可以访问相关网站,获取更多关于密码学的知识和资源。
-
交流平台
:可以通过电子邮件或论坛与其他爱好者交流,分享经验和解决问题。
总结回顾
本文详细介绍了Python中的列表插入操作、消息的加密和解密方法、密钥文件的读取和写入,以及如何使用IDLE的调试器来查找程序中的错误。通过学习这些内容,你可以掌握基本的加密和解密原理,并能够使用Python实现简单的加密和解密功能。
同时,我们也强调了在实际应用中要注意的安全问题,不建议使用本文介绍的程序来保护重要的秘密文件,而是应该选择专业的加密软件。希望本文能够为你提供一个良好的学习基础,鼓励你继续探索编程和密码学的更多知识。
以下是本文涉及的主要函数及其功能的再次总结:
| 函数名 | 功能 |
| ---- | ---- |
|
insert()
| 在列表指定索引位置插入值 |
|
encryptMessage()
| 对消息进行加密,返回加密块列表 |
|
decryptMessage()
| 对加密块进行解密,返回解密后的消息字符串 |
|
readKeyFile()
| 从密钥文件中读取密钥信息,返回元组 |
|
encryptAndWriteToFile()
| 加密消息并将结果写入文件,返回加密字符串 |
|
readFromFileAndDecrypt()
| 从文件中读取加密消息并进行解密,返回解密后的消息字符串 |
|
main()
| 程序的主函数,根据条件调用 |
通过这些函数的组合使用,我们可以实现一个完整的加密和解密系统。同时,利用IDLE的调试器,我们可以更方便地排查程序中的错误,提高开发效率。
希望你在学习和实践过程中能够不断积累经验,提升自己的编程和密码学能力。如果你在学习过程中遇到任何问题,欢迎通过上述提到的交流平台寻求帮助。祝你在编程和密码学的道路上取得更好的成绩!
超级会员免费看
2万+

被折叠的 条评论
为什么被折叠?



