【python】块加密-保存和读取密钥

  • Post author:
  • Post category:python




一、全部代码块

"""
简单的块加密程序 - 中英文支持 v2
中英文同时构造一个矩阵使用
By JerryLiu
20210418
"""

import random
import pickle

# Const define for Chinese  and English
ROW = 145
COL = 145
startCodeCN = 0x4e00

# Const define for English
ROW_EN = 5
COL_EN = 19
startCodeEN = 32


def makeMatrixCNEN():
    """构造随机字符矩阵,为一个列表的列表,循环语句"""
    listOfChars = []
    for offside in range(ROW * COL - ROW_EN * COL_EN):
        listOfChars.append(chr(startCodeCN + offside))  # 添加中文字符

    listOfEnglishChars = []
    for offside in range(ROW_EN * COL_EN):
        listOfChars.append(chr(startCodeEN + offside))  # 添加ascii字符
    # print(listOfChars[:10])
    random.shuffle(listOfChars)
    # print(listOfChars[:10])
    matrix = []
    for row in range(ROW):
        matrix.append([])
        for column in range(COL):
            matrix[row].append(listOfChars[row * COL + column])
    # print(matrix[0][:10])
    return matrix


def printMatrix(matrix):
    """打印加密矩阵"""
    rowNum = len(matrix)
    colNum = len(matrix[0])
    if rowNum > 10:
        rowNum = 10
        print("矩阵行数大于10,仅显示前10行")
    if colNum > 10:
        colNum = 10
        print("矩阵列数大于10,仅显示前10列")
    print("-" * 10)
    for row in range(rowNum):
        for column in range(colNum):
            print(matrix[row][column], end=' ')
        print()
    print("-" * 10)


def findCharInMatrix(matrix, targetChar):
    """查找某个字符在加密矩阵中的位置,找到返回行和列,如果找不到返回none"""
    rowNum = len(matrix)
    colNum = len(matrix[0])
    for row in range(rowNum):
        for column in range(colNum):
            if matrix[row][column] == targetChar:
                return row, column
    return -1, -1


def encrypt(plainText, matrix):
    """使用matrix加密原始文本plainText,返回值为加密后的文本"""
    cypherText = ""
    lenText = len(plainText)
    # 判断是否为奇数个字符,如果是,则最后一位无需加密处理
    if lenText % 2 == 1:
        lenText -= 1
    # 使用矩阵,加密一对字符
    i = 0
    while i < lenText:
        cypherText += encryptPair(plainText[i:i + 2], matrix)
        i += 2
    # 如果是奇数个字符,则将最后一位直接附加在最后即可
    if lenText < len(plainText):
        cypherText += plainText[-1]
    return cypherText


def IsASCiiChar(c):
    if ord(c) >= 32 and ord(c) <= 126:
        return True
    else:
        return False


def decrypt(cipherText, matrix):
    """解密函数,同加密算法一样"""
    return encrypt(cipherText, matrix)


def encryptPair(orgPair, matrix):
    """加密一对字符"""
    afterChar0 = ''
    afterChar1 = ''
    (row1, col1) = findCharInMatrix(matrix, orgPair[0])
    (row2, col2) = findCharInMatrix(matrix, orgPair[1])
    if row1 == -1 or row2 == -1:  # 增加判断,防止找不到字符的错误
        afterChar0 = orgPair[0]
        afterChar1 = orgPair[1]
    else:
        if row1 == row2 or col1 == col2:  # 如果在同一行或同一列,则直接互换位置即可,否则进行对角线互换
            afterChar0 = orgPair[1]
            afterChar1 = orgPair[0]
        else:
            afterChar0 = matrix[row2][col1]
            afterChar1 = matrix[row1][col2]
    return afterChar0 + afterChar1


def GenerateKey():
    """产生密钥,即产生 随机字符矩阵,并保存为文件"""
    global matrix  # 声明全局变量
    matrix = makeMatrixCNEN()  # 产生矩阵
    # -----完成下面功能--------
    # 用户输入需要保存的密钥文件路径
    # 二进制序列化matrix并保存为fileName.mat
    address = input("请输入需要保存的密钥文件路径:")
    with open(f"{address}", 'wb') as f2:
        try:
            pickle.dump(matrix, f2)
            print("保存成功")
        except:
            print("存文件异常!")



def LoadKey():
    """从文件中 载入密钥"""
    global matrix  # 声明全局变量
    # -----完成下面功能--------
    # 用户输入需要载入的密钥文件路径
    # 读取fileName, 到matrix中,显示读取成功
    address = input("请输入需要载入的密钥文件路径:")
    with open(f'{address}', 'rb') as f1:
        try:
            matrix = pickle.load(f1)
            print("读取成功")
        except:
            print("读取文件异常!")


def EncryptText():
    global matrix
    if matrix is None:
        print("当前密钥为空,需要生成或者读取密钥,再进行加密")
        return
    plainText = input("请输入加密文本: ")
    cipherText = encrypt(plainText, matrix)
    print("加密中 . . .\n",
          "原始文本: " + plainText,
          "\n加密文本: " + cipherText)


def DecryptText():
    global matrix
    if matrix is None:
        print("当前密钥为空,需要生成或者读取密钥,再进行解密")
        return
    cipherText = input("请输入解密文本: ")
    oldText = decrypt(cipherText, matrix)
    print("解密中 . . .\n",
          "加密文本: " + cipherText,
          "\n原始文本: " + oldText)


def showMatrix():
    global matrix
    if matrix is None:
        print("当前密钥为空,需要生成或者读取密钥,再进行解密")
        return
    printMatrix(matrix)


def main():
    while True:
        print("-" * 20)
        print("0-退出")
        print("1-生成并保存密钥")
        print("2-载入密钥")
        print("3-加密文本")
        print("4-解密文本")
        print("5-显示密钥")
        print("-" * 20)
        userSelect = input("请选择操作:")
        if userSelect == "0":
            break  # 退出
        elif userSelect == "1":
            GenerateKey()  # 生成并保存密钥
        elif userSelect == "2":
            LoadKey()  # 读取密钥
        elif userSelect == "3":
            EncryptText()  # 加密文本
        elif userSelect == "4":
            DecryptText()  # 解密文本
        elif userSelect == "5":
            showMatrix()  # 显示密钥
        else:
            print("选择错误,请重新选择")


if __name__ == "__main__":
    matrix = None
    main()



二、需要写的部分

def GenerateKey():
    """产生密钥,即产生 随机字符矩阵,并保存为文件"""
    global matrix  # 声明全局变量
    matrix = makeMatrixCNEN()  # 产生矩阵
    # -----完成下面功能--------
    # 用户输入需要保存的密钥文件路径
    # 二进制序列化matrix并保存为fileName.mat
    address = input("请输入需要保存的密钥文件路径:")
    # E:\桌面\a.bat 或 a.bat ,不要少量bat的文件就行
    with open(f"{address}", 'wb') as f2:
        try:
            pickle.dump(matrix, f2)
            print("保存成功")
        except:
            print("存文件异常!")



def LoadKey():
    """从文件中 载入密钥"""
    global matrix  # 声明全局变量
    # -----完成下面功能--------
    # 用户输入需要载入的密钥文件路径
    # 读取fileName, 到matrix中,显示读取成功
    address = input("请输入需要载入的密钥文件路径:")
    # 输入一个文件名也行
    # E:\桌面\a.bat 或 a.bat
    with open(f'{address}', 'rb') as f1:
        try:
            matrix = pickle.load(f1)
            print("读取成功")
        except:
            print("读取文件异常!")

真的大厦崩塌了,为数不多的快乐也没有了。



版权声明:本文为weixin_45759918原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。