1_单表代换和多表代换
Posted H3rmesk1t
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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_单表代换和多表代换的主要内容,如果未能解决你的问题,请参考以下文章