1_单表代换和多表代换

实验目的

通过实验熟练掌握凯撒密码和Hill密码算法原理,编程实现加密算法,熟悉模运算和扩展欧几里德算法

实验环境

PyCharm

实验要求

单表代换:编程实现凯撒密码,输入任意一段明文,对其加密并输出密文
多表代换:编程实现Hill加密算法,输入一段无空格的五个小写字母明文,对其加密并输出密文
撰写实验报告

实验内容

单表代换:
凯撒密码密钥为3,从文本文件中读取明文,用密钥加密,密文保存于对应密文数组
多表代换:
1.密钥生成:Hill加密的密钥矩阵K随机生成,需要进行在模26的意义下进行可逆性检测,这里可以用求行列式模26的逆元
2.读取明文并预处理:输入的明文是5个小写字母,彼此之间没有空格,而后放入5个元素的明文数组
3.加密:将密钥矩阵与明文数组左乘,在模26的意义下,生成密文数组
4.解密:将密钥矩阵的伴随阵D求出,左乘密文数组,再乘密钥矩阵行列式的逆,从而完成逆矩阵左乘,都在模26的意义下

实验代码

凯撒密码

# -*- coding: utf-8 -*-
# @Time    : 2021/5/10 21:48
# @Author  : H3rmesk1t
# @FileName: 凯撒密码.py
# @Software: PyCharm
# @Blog    :https://blog.csdn.net/LYJ20010728/
with open('凯撒密码.txt') as file_object:
    contents = file_object.read()
# 获取密钥值
key = eval(input("Please input your key number:\n"))
# 获取操作模式
mode = input("Please input mode (encrypt or decrypt):\n") or "encrypt"
# 明文字母表
symbols = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 !?.'
# 根据数字 key 对字母表 symbols 进行偏移操作,形成密文字母表 ciphers
ciphers = symbols[key:] + symbols[:key]
# 根据加密与解密动作,生成明文字母到密文字母(或密文到明文)的对应关系
transtab = str.maketrans(symbols, ciphers) if mode == 'encrypt' else str.maketrans(ciphers, symbols)
# 完成明文到密文(或密文到明文)的转换
result = contents.translate(transtab)
# 输出明文及密文
print(f"The initial content is:\n{contents}")
print(f"The result is:\n{result}\n")

在这里插入图片描述

Hill密码

# -*- coding: utf-8 -*-
# @Time    : 2021/5/10 22:07
# @Author  : H3rmesk1t
# @FileName: Hill密码.py
# @Software: PyCharm
# @Blog    :https://blog.csdn.net/LYJ20010728/
import numpy as np

#26个字母列表:方便找出对应下标
ALPHABET = ["A","B","C","D","E","F","G",
            "H","I","J","K","L","M","N",
            "O","P","Q","R","S","T","U",
            "V","W","X","Y","Z"]

# 产生矩阵并判断矩阵是否存在逆矩阵(即判断能否解密)
def inputMatrix(n):
    # 随机矩阵生成
    arr = np.random.randint(0, 26, (n, n))
    while True:
        if not judgeInverse(arr):
            continue
        else:
            print(f"生成的随机矩阵为:\n{arr}")
            return arr

# 判断随机矩阵是否存在逆元
def judgeInverse(matrix):
    try:
        np.linalg.inv(matrix)
    except:
        return False
    return True

# 获得字母在字母表中的对应位置(下标)
def get_index(alphabet):
    alphabet = alphabet.upper()
    return ALPHABET.index(alphabet)

# 加密处理C=KP
def deal_index(list_index):
    deal_list = [0,0,0]
    for i in range(len(arr)):
        for j in range(len(arr[i])):
            deal_list[i] += list_index[j] * arr[i][j]
        deal_list[i] = (deal_list[i] % 26)
    return deal_list

# 通过字母的下标获得对应字母
def get_alphabet(deal_list):
    cipher_list = []
    for i in deal_list:
        cipher_list.append(ALPHABET[i].lower())
    return cipher_list

# 加密时调用的函数
def encryption(clear_text):
    list_clear_text = list(clear_text.strip().replace(" ", ""))
    # print(list_clear_text)
    #明文每3个一组,不足则补充字母Z
    for i in range(len(list_clear_text)):
        if i % 3 == 0 and i+2 > len(list_clear_text)-1:  # 越界,则需在最后一组不足3个补字母Z
            if i+1 > len(list_clear_text)-1:
                list_clear_text.insert(i + 1, "Z")
            list_clear_text.insert(i + 2, "Z")
    # print(list_clear_text)
    cipher_list = []   #用来存入密文
    #明文每3个为一组,找出每组在字母表中的位置(用一个列表来保存)
    for i in range(len(list_clear_text)):
        if i % 3 == 0 and i+2 <= len(list_clear_text)-1:
            x = get_index(list_clear_text[i])
            y = get_index(list_clear_text[i+1])
            z = get_index(list_clear_text[i+2])
            list_index = [x, y, z]
            # print(list_index)
            #调用deal_inde函数进行加密 矩阵K与明文P运算得到密文C,即C=KP
            deal_list = deal_index(list_index)
            part_cipher_list = get_alphabet(deal_list)   #返回一组密文
            cipher_list.extend(part_cipher_list)

    # print(cipher_list)
    return "".join(cipher_list)

if __name__ == "__main__":
    # 获取随机矩阵的大小
    n = eval(input("请输入随机矩阵(nxn)的大小n:\n"))
    arr = inputMatrix(n)
    # 读入明文
    with open('Hill密码.txt') as file_object:
        Plaintext = file_object.read()
    # 明文加密
    # 随机矩阵大小暂且默认为3,若需要改变,改动加密函数中的明文分组大小即可
    print(f"读入的明文为:\n{Plaintext}")
    print(f"输出的密文为:\n{encryption(Plaintext)}")

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值