思路分析:
我们根据相关材料,根据希尔密码的相关知识总结了我们的思路。希尔密码是运用基本矩阵乘法原理的替换密码,我们以 65 65 65表示 A A A, 66 66 66表示 B B B,……, 88 88 88表示 Y Y Y, 89 89 89表示 Z Z Z( A S C I ASCI ASCI值),以此类推。我们将需要加密的一串字母当成 n n n维向量,根一个 n ∗ n n*n n∗n的矩阵相乘(即加密矩阵),再将得出的结果 m o d mod mod 26 26 26。我们还需要对给定的加密矩阵进行判断,加密矩阵必须是可逆的,否则就不能用来作为加密矩阵。(只有矩阵的行列式和26互质才是可逆的)
明文:
明文经过加密过程的变换所得的消息或字符串。
加密过程
:将明文变换成另一种不能被非授权者所理解的隐蔽信息。
密文
:明文经过加密过程的变化,所得的消息或字符串。
加密变换
:将明文变为密文的变换。
密钥
:加密变化所使用的参数。
首先,我们将所加密信息用 A S C I ASCI ASCI值替换,得到了一个 n n n维向量阶矩阵,然后输入 n ∗ n n*n n∗n的合法加密矩阵得到密文,用解密矩阵对所得密文求解得原来加密中的信息。
例如:
其中,我们需要加密的信息为:WEARETHECHAMPION
,所以
密
文
矩
阵
X
为
[
87
69
65
82
69
84
72
69
67
72
65
77
80
73
79
78
]
,
密文矩阵X为\left[\begin{array}{cccc}87& 69& 65& 82\\ 69& 84& 72& 69\\ 67& 72& 65& 77\\ 80& 73& 79& 78\end{array}\right],
密文矩阵X为⎣⎢⎢⎡87696780698472736572657982697778⎦⎥⎥⎤,
秘
钥
矩
阵
A
为
[
0
0
0
1
0
0
1
1
0
1
1
1
1
1
1
1
]
,
秘钥矩阵A为\left[\begin{array}{cccc}0& 0& 0& 1\\ 0& 0& 1& 1\\ 0& 1& 1& 1\\ 1& 1& 1& 1\end{array}\right],
秘钥矩阵A为⎣⎢⎢⎡0001001101111111⎦⎥⎥⎤,
明
文
矩
阵
Y
为
[
82
82
86
82
69
76
69
73
77
77
84
86
78
66
74
89
]
,
明文矩阵Y为\left[\begin{array}{cccc}82& 82& 86& 82\\ 69& 76& 69& 73\\ 77& 77& 84& 86\\ 78& 66& 74& 89\end{array}\right],
明文矩阵Y为⎣⎢⎢⎡82697778827677668669847482738689⎦⎥⎥⎤,
解
密
矩
阵
A
−
1
为
[
0
0
25
1
0
25
1
0
25
1
0
0
1
0
0
0
]
解密矩阵{A}^{-1}为\left[\begin{array}{cccc}0& 0& 25& 1\\ 0& 25& 1& 0\\ 25& 1& 0& 0\\ 1& 0& 0& 0\end{array}\right]\phantom{\rule{0ex}{0ex}}
解密矩阵A−1为⎣⎢⎢⎡0025102510251001000⎦⎥⎥⎤
根据原理:
X ∗ A = Y X*A=Y\phantom{\rule{0ex}{0ex}} X∗A=Y
Y ∗ A − 1 = X Y*{A}^{-1}=X Y∗A−1=X
我们就可以对唯一的给定的密文和 n ∗ n n*n n∗n的加密矩阵,求出对应的明文和解密矩阵。
详细代码:
# i:/vscode/vscode_python/.vscode/数学建模
# -*- coding: utf-8 -*-
'''
@Time : 2019/11/20 19:51
@Author : nuoyanli
@Version : 1.0
@Contact : 2531649293@qq.com
@Site : 2.79KB
@File : 希尔密码.py
@Software: VSCode
'''
import numpy as np
def gcd(a, b):
if a % b == 0:
return b
else:
return gcd(b, a % b)
def encode(string, size):
# 只转换大写字母
if not string.isupper():
return None
# 分成 size 字的分段
blocks = [string[i:i+size] for i in range(0, len(string), size)]
temp = np.array([list(map(ord, block)) for block in blocks]) - ord('A')
return temp
def analysis(crypter, code):
return ((crypter @ code.T) % 26).T + ord('A')
if __name__ == '__main__':
# 要加密的信息
while True:
print('请输入待加密的信息:(请务必保证加密信息只包含大写字母)')
Clear_text = input()
le = len(Clear_text)
print('待加密的信息为:\n' + Clear_text)
n = le
# print('请选择加密矩阵的大小n作为n*n的加密矩阵(请务必保证矩阵合法):')
# n = int(input())
# if len(Clear_text) % n != 0:
# print('该密文和加密矩阵不合法!')
# else:
# break
print('请输入', n, '行每行', n, '个数,每行的数用空格隔开')
matrix = [[0] * (n)] * (n)
for i in range(n):
matrix[i] = list(map(int, input().split(' ')))
# 加密矩阵
vis = np.linalg.det(matrix)
if gcd(vis, 26) == 1:
Encryption_matrix = matrix
print('加密矩阵为:')
for i in range(n):
for j in range(n):
print(Encryption_matrix[i][j], end='')
if j == (n - 1):
print('')
else:
print(' ', end=' ')
# print(matrix)
# 加密代码
Encrypted_fun = analysis(Encryption_matrix, encode(Clear_text, le))
print('待加密信息转换为加密矩阵,加密矩阵为:')
for i in range(le):
if i == (le - 1):
print(Encrypted_fun[0][j])
else:
print(Encrypted_fun[0][i], end=' ')
# 密文
Ciphertext_matrix = ''.join(map(chr, Encrypted_fun.ravel()))
print("密文为:\n" + Ciphertext_matrix)
# 解密矩阵
decrypter = np.linalg.inv(Encryption_matrix).astype('int32') % 26
print('解密矩阵:')
for i in range(n):
for j in range(n):
print(decrypter[i][j], end='')
if j == (n - 1):
print('')
else:
print(' ', end=' ')
# 解密代码
Decryption_fun = analysis(decrypter, encode(Ciphertext_matrix, le))
print('获得解密信息的矩阵:')
for i in range(le):
if i == (le - 1):
print(Decryption_fun[0][i])
else:
print(Decryption_fun[0][i], end=' ')
# 明文
Clear_text = ''.join(map(chr, Decryption_fun.ravel()))
print('明文为:\n' + Clear_text)
else:
print('输入的加密矩阵不合法矩阵,请重新输入明文和加密矩阵!')
x = int(input('请输入数字选择1继续,2结束[1/2]:'))
if x == 2:
break