【python】 中英文混合块加密算法&&文本文件的块加密

【python】 中英文混合块加密算法&&文本文件的块加密,第1张

文章目录
  • 一、中英文混合块加密算法
    • 一、安装 numpy 包
    • 二、需求
    • 三、参考答案
  • 二、文本文件的块加密
    • 一、安装 numpy 包
    • 二、需求
  • **注意!注意!注意!**
    • 三、参考答案
    • 四、例子

一、中英文混合块加密算法 一、安装 numpy 包

方法如下:https://blog.csdn.net/weixin_45759918/article/details/124532318

二、需求

在英文块加密的基础上,完成中英文混合的块加密算法,中文字符从0x4e00开始,矩阵大小为145*145。

分析:这次的密码本需要多种形式组成,所以可以把字符先转为Unicode码的十进制形式再放入不同数组中。
密码本组成 = 中文Unicode字符 + 英文和标点Unicode字符 + 中文标点Unicode字符
145*145 = 20908 + 95 + 22
因为中文的标点符号在Unicode并不连续所以要单独列出来
其他的算法和加密英文没有区别,改改数就行。
注意:输入的字符有时有两个一样的内容(a=[‘人’,‘人’]),加密解密时设置跳过相同字符,要不然加密解密都出错。

中文标点符号的列表

chinesePunctuationList = [183, 215, 8212, 8216, 8217, 8220, 8221, 8230, 12289, 12290, 12298, 12302, 12303, 12304,
                              12305, 65281, 65288, 65289, 65292, 65306, 65307, 65311]

可以参考这个图

三、参考答案
import numpy as np


# \u4e00到\u9FAC  +  32到126的单词字符 + 22个中文标点 == 145 ** 2
def makeMatrix():
    # 生成32-126的数字,过会放到汉字加密中
    englishCharactersList = []
    # 装填范围到checkList中(ascii码的规定可显示字符范围)
    i = 32
    while (i != 127):
        englishCharactersList.append(i)
        i += 1
    # 生成汉字的随机密码本
    chineseCharactersList = []
    # 4E00到9FC2 转为十进制为 19968-40876
    j = 19968
    while (j != 40877):
        chineseCharactersList.append(j)
        j += 1
    # 这里是中文的标点符号,还是要加进去的要不然出错了就。一共22个
    chinesePunctuationList = [183, 215, 8212, 8216, 8217, 8220, 8221, 8230, 12289, 12290, 12298, 12302, 12303, 12304,
                              12305, 65281, 65288, 65289, 65292, 65306, 65307, 65311]
    allList = englishCharactersList + chineseCharactersList + chinesePunctuationList
    # 对两个矩阵的和进行乱序 145*145=21025
    # data --->> 乱序后的列表
    data = np.random.choice(allList, size=21025, replace=False)
    # 创建一个145行145列的二维矩阵,填充内容为'k'
    # words --->> 密码本
    words = np.full((145, 145), 'k')
    # 用于遍历data中的数
    x = 0
    # 循环将data中生成随机数输入words的二维矩阵。
    for i in range(145):
        for j in range(145):
            # 随机的数字直接转为字符
            words[i, j] = chr(int(data[x]))
            x += 1
    return words


# 将输入的字符分割为两两一组的二维矩阵
# 输入: text --->> 用户输入
# 输出: data --->> 分割后的用户输入字符
def segmentationText(text):
    # 分割为一维数组
    textList = list(text)
    if len(textList) % 2 != 0:
        textList.append(" ")
    data = []
    for index in range(0, len(textList), 2):
        data.append(textList[index:index + 2])
    data = np.array(data)
    # print(f"分割后数据为:\n{data}")
    return data


# 加密过程
# 块加密:生成一个随机的acsii可视范围的密码本(二维矩阵),然后将明文分为两个字母一组的二维矩阵
# 设[A,B],其在二维矩阵的密码本中位置为 A(i,j),B(x,y)
# 如果其在密码本中同一列或同行,则互换内容 加密后为[C,D]其中 C(x,y),D(i,j) 等价于加密后密文为 [B,A]
# 若不在同行同列,则加密后为[C,D]其中 C(x,j),D(i,y) 等价于横坐标不变纵坐标变为对方纵坐标
# 输入: words --->> 密码本; data --->> 分割后的用户输入; text --->> 用户原输入
# 输出:cipher --->> 加密后文本
def encryption(words, data, text):
    # 密文
    cipher = []
    for i in range(len(data)):
        A = data[i, 0]
        B = data[i, 1]
        Ax, Ay, Bx, By = 0, 0, 0, 0
        # 如果两个字一样,确实要跳过,要不然解密加密都出问题
        if A == B:
            cipher.append(A)
            cipher.append(B)
            continue
        # 找到密码本中需要加密的文字的横纵坐标
        for x in range(145):
            for y in range(145):
                if words[x, y] == A:
                    Ax = int(x)
                    Ay = int(y)
                elif words[x, y] == B:
                    Bx = int(x)
                    By = int(y)
        # 判断同行同列,是则交换数据
        if Ax == Bx or Ay == By:
            A, B = B, A
        else:
            A = words[Bx, Ay]
            B = words[Ax, By]
        cipher.append(A)
        cipher.append(B)
    cipherStr = "".join(cipher)
    print(f"原文为:{text}")
    print(f"加密后文本为:{cipherStr}")
    return cipher


# 解密,就是加密逆过程
# 同列同行交换的,换回来
# C(x,j),D(i,y)换回A(x,y),B(i,j)
# 输入:cipher  --->> 加密后文本; words --->> 密码本; text --->> 用户原输入
def decryption(cipher, words, text):
    # 密文转为二维矩阵
    cipherList = segmentationText(cipher)
    # 破解翻译后的明文
    clear = []
    for i in range(len(cipherList)):
        A = cipherList[i, 0]
        B = cipherList[i, 1]
        Ax, Ay, Bx, By = 0, 0, 0, 0
        # 如果两个字一样,确实要跳过,要不然解密加密都出问题
        if A == B:
            clear.append(A)
            clear.append(B)
            continue
        # 找到密码本中需要加密的文字的横纵坐标
        for x in range(145):
            for y in range(145):
                if words[x, y] == A:
                    Ax = int(x)
                    Ay = int(y)
                elif words[x, y] == B:
                    Bx = int(x)
                    By = int(y)
        # 判断同行同列,是则交换数据
        if Ax == Bx or Ay == By:
            A, B = B, A
        else:
            A = words[Bx, Ay]
            B = words[Ax, By]
        clear.append(A)
        clear.append(B)
    clearStr = "".join(clear)
    print(f"原文为:{text}")
    print(f"解密为:{clearStr}")


text = input("请输入需要加密的字符串:")
words = makeMatrix()
data = segmentationText(text)
print(f"分割后数据为:\n{data}")
cipher = encryption(words, data, text)
decryption(cipher, words, text)

二、文本文件的块加密 一、安装 numpy 包

方法如下:https://blog.csdn.net/weixin_45759918/article/details/124532318

二、需求

增加了从文件中读取到写入文件的问题,并且要将文件名也加密,其实只是入口不一样了,别的没有变化。
在读文件时候注意把**\n**这个东西去掉,要不然保存出问题

注意!注意!注意!

需要加密的文件放在与py文件同一个文件夹下,这样可以直接写文件名,保存也会默认保存在这里。否则请使用绝对路径。

三、参考答案
import numpy as np
import os


# \u4e00到\u9FAC  +  32到126的单词字符 + 22个中文标点 == 145 ** 2
def makeMatrix():
    # 生成32-126的数字,过会放到汉字加密中
    englishCharactersList = []
    # 装填范围到checkList中(ascii码的规定可显示字符范围)
    i = 32
    while (i != 127):
        englishCharactersList.append(i)
        i += 1
    # 生成汉字的随机密码本
    chineseCharactersList = []
    # 4E00到9FC2 转为十进制为 19968-40876
    j = 19968
    while (j != 40877):
        chineseCharactersList.append(j)
        j += 1
    # 这里是中文的标点符号,还是要加进去的要不然出错了就。一共22个
    chinesePunctuationList = [183, 215, 8212, 8216, 8217, 8220, 8221, 8230, 12289, 12290, 12298, 12302, 12303, 12304,
                              12305, 65281, 65288, 65289, 65292, 65306, 65307, 65311]
    allList = englishCharactersList + chineseCharactersList + chinesePunctuationList
    # 对两个矩阵的和进行乱序 145*145=21025
    # data --->> 乱序后的列表
    data = np.random.choice(allList, size=21025, replace=False)
    # 创建一个145行145列的二维矩阵,填充内容为'k'
    # words --->> 密码本
    words = np.full((145, 145), 'k')
    # 用于遍历data中的数
    x = 0
    # 循环将data中生成随机数输入words的二维矩阵。
    for i in range(145):
        for j in range(145):
            # 随机的数字直接转为字符
            words[i, j] = chr(int(data[x]))
            x += 1
    return words


# 将输入的字符分割为两两一组的二维矩阵
# 输入: text --->> 用户输入
# 输出: data --->> 分割后的用户输入字符
def segmentationText(text):
    # 分割为一维数组
    textList = list(text)
    if '\n' in textList:
        x = 0
        for i in range(len(textList)):
            if i == "\n":
                textList[x] == " "
            x += 1
    # 如果输入的内容拆分后不为偶数,则给其末尾加个空格。
    if len(textList) % 2 != 0:
        textList.append(" ")
    data = []
    for index in range(0, len(textList), 2):
        data.append(textList[index:index + 2])
    data = np.array(data)
    # print(f"分割后数据为:\n{data}")
    return data


# 加密过程
# 块加密:生成一个随机的acsii可视范围的密码本(二维矩阵),然后将明文分为两个字母一组的二维矩阵
# 设[A,B],其在二维矩阵的密码本中位置为 A(i,j),B(x,y)
# 如果其在密码本中同一列或同行,则互换内容 加密后为[C,D]其中 C(x,y),D(i,j) 等价于加密后密文为 [B,A]
# 若不在同行同列,则加密后为[C,D]其中 C(x,j),D(i,y) 等价于横坐标不变纵坐标变为对方纵坐标
# 输入: words --->> 密码本; data --->> 分割后的用户输入; text --->> 用户原输入
# 输出:cipher --->> 加密后文本
# 加密过程
# 块加密:生成一个随机的acsii可视范围的密码本(二维矩阵),然后将明文分为两个字母一组的二维矩阵
# 设[A,B],其在二维矩阵的密码本中位置为 A(i,j),B(x,y)
# 如果其在密码本中同一列或同行,则互换内容 加密后为[C,D]其中 C(x,y),D(i,j) 等价于加密后密文为 [B,A]
# 若不在同行同列,则加密后为[C,D]其中 C(x,j),D(i,y) 等价于横坐标不变纵坐标变为对方纵坐标
# 输入: words --->> 密码本; data --->> 分割后的用户输入; text --->> 用户原输入
# 输出:cipher --->> 加密后文本
def encryption(words, data, text):
    # 密文
    cipher = []
    for i in range(len(data)):
        A = data[i, 0]
        B = data[i, 1]
        Ax, Ay, Bx, By = 0, 0, 0, 0
        # 如果两个字一样,确实要跳过,要不然解密加密都出问题
        if A == B:
            cipher.append(A)
            cipher.append(B)
            continue
        # 找到密码本中需要加密的文字的横纵坐标
        for x in range(145):
            for y in range(145):
                if words[x, y] == A:
                    Ax = int(x)
                    Ay = int(y)
                elif words[x, y] == B:
                    Bx = int(x)
                    By = int(y)
        # 判断同行同列,是则交换数据
        if Ax == Bx or Ay == By:
            A, B = B, A
        else:
            A = words[Bx, Ay]
            B = words[Ax, By]
        cipher.append(A)
        cipher.append(B)
    cipherStr = "".join(cipher)
    print(f"原文为:{text}")
    print(f"加密后文本为:{cipherStr}")
    return cipher


# 解密,就是加密逆过程
# 同列同行交换的,换回来
# C(x,j),D(i,y)换回A(x,y),B(i,j)
# 输入:cipher  --->> 加密后文本; words --->> 密码本; text --->> 用户原输入
def decryption(cipher, words, text):
    # 密文转为二维矩阵
    cipherList = segmentationText(cipher)
    # 破解翻译后的明文
    clear = []
    for i in range(len(cipherList)):
        A = cipherList[i, 0]
        B = cipherList[i, 1]
        Ax, Ay, Bx, By = 0, 0, 0, 0
        # 如果两个字一样,确实要跳过,要不然解密加密都出问题
        if A == B:
            clear.append(A)
            clear.append(B)
            continue
        # 找到密码本中需要加密的文字的横纵坐标
        for x in range(145):
            for y in range(145):
                if words[x, y] == A:
                    Ax = int(x)
                    Ay = int(y)
                elif words[x, y] == B:
                    Bx = int(x)
                    By = int(y)
        # 判断同行同列,是则交换数据
        if Ax == Bx or Ay == By:
            A, B = B, A
        else:
            A = words[Bx, Ay]
            B = words[Ax, By]


        clear.append(A)
        clear.append(B)
    clearStr = "".join(clear)
    print(f"原文为:{text}")
    print(f"解密为:{clearStr}")


# 读文件内容转字符串
# 输入:文件名
# 输出:读取的字符串
def readFile(fileName):
    strs = ""
    # 这样写读取完文件程序会自动关闭文件,不用手动关闭
    with open(fileName, 'r', encoding="UTF-8", newline=None) as file:
        strs = file.read().splitlines()
        st = "".join(strs)
        return st


# 写入文件
# 输入:cipher --->> 加密后文本;fileName --->> 文件名;words --->> 密码本
def writeFile(cipher, fileName, words):
    # 加密后的文件名
    encryptionFileName = str(fileName.split(".")[0])
    # 加工后的文件名
    fileNameData = segmentationText(encryptionFileName)
    # 加密后的文件名
    fileNamecipher = encryption(words, fileNameData, encryptionFileName)
    # 加密和组合文件名
    st = "".join(fileNamecipher) + "." + fileName.split(".")[-1]
    # 写入文件
    with open(st, "w", encoding="UTF-8") as op:
        op.write("加密后文本为:" + "".join(cipher))
        op.close()
    # 打开加密后的文件
    os.system("notepad "+fileName+" && "+"notepad "+st)


fileName = input("请输入需要加密的文件名:")
# 文件名
text = readFile(fileName)
# 密码本
words = makeMatrix()
# 加工后的用户输入
data = segmentationText(text)
print(f"分割后数据为:\n{data}")
# 加密文本
cipher = encryption(words, data, text)
# 解密文本
decryption(cipher, words, text)
# 文件写入
writeFile(cipher, fileName, words)

四、例子

加密前:

加密后:

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/801381.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-07
下一篇 2022-05-07

发表评论

登录后才能评论

评论列表(0条)

保存