33、Python加密解密与调试全解析

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的调试器,我们可以更方便地排查程序中的错误,提高开发效率。

希望你在学习和实践过程中能够不断积累经验,提升自己的编程和密码学能力。如果你在学习过程中遇到任何问题,欢迎通过上述提到的交流平台寻求帮助。祝你在编程和密码学的道路上取得更好的成绩!

MATLAB代码实现了一个基于多种智能优化算法优化RBF神经网络的回归预测模型,其核心是通过智能优化算法自动寻找最优的RBF扩展参数(spread),以提升预测精度。 1.主要功能 多算法优化RBF网络:使用多种智能优化算法优化RBF神经网络的核心参数spread。 回归预测:对输入特征进行回归预测,适用于连续值输出问题。 性能对比:对比不同优化算法在训练集和测试集上的预测性能,绘制适应度曲线、预测对比图、误差指标柱状图等。 2.算法步骤 数据准备:导入数据,随机打乱,划分训练集和测试集(默认7:3)。 数据归一化:使用mapminmax将输入和输出归一化到[0,1]区间。 标准RBF建模:使用固定spread=100建立基准RBF模型。 智能优化循环: 调用优化算法(从指定文件夹中读取算法文件)优化spread参数。 使用优化后的spread重新训练RBF网络。 评估预测结果,保存性能指标。 结果可视化: 绘制适应度曲线、训练集/测试集预测对比图。 绘制误差指标(MAE、RMSE、MAPE、MBE)柱状图。 十种智能优化算法分别是: GWO:灰狼算法 HBA:蜜獾算法 IAO:改进天鹰优化算法,改进①:Tent混沌映射种群初始化,改进②:自适应权重 MFO:飞蛾扑火算法 MPA:海洋捕食者算法 NGO:北方苍鹰算法 OOA:鱼鹰优化算法 RTH:红尾鹰算法 WOA:鲸鱼算法 ZOA:斑马算法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值