多表代换密码原理
多表代换密码首先将明文M分成由n个字母构成的分组$M_1,M_2,\cdots ,M_j$,
对每个分组的$M_i$的加密为:
其中,(A,B)是密钥,A是n X n 的可逆矩阵,满足gcd(|A|,N)= 1,
B = $(B_1,B_2,\cdots,B_n)^T$, C = $(C_1,C_2,\cdots,C_n)^T$, $\mathbf{M}_i$ = $(m_1,m_2,\cdots,m_n)^T$.
对每个分组的$C_i$的解密为:
例如:
加密过程:
n = 3, N = 26
message: you ……(此处就只举例第一个分组了)
you —-> $\mathbf{M}_1$ = $\begin{pmatrix}
24 \
14 \
20
\end{pmatrix}$ , $\mathbf{C}_1$ = $\mathbf{A}$ $\begin{pmatrix}
24 \
14 \
20
\end{pmatrix}$ = $\begin{pmatrix}
22 \
6 \
8
\end{pmatrix}$ . 我们可以知道22,6,8对应的是W,G,I. 加密就此完成。
解密过程:
解密时,先求出
再求:$\mathbf{M}_1$ = $\mathbf{A}^{-1}$ $\begin{pmatrix}
22 \
6 \
8
\end{pmatrix}$ = $\begin{pmatrix}
24 \
14 \
20
\end{pmatrix}$ . $\begin{pmatrix}
24 \
14 \
20
\end{pmatrix}$ —->you. 至此,解密完成。
代码部分:
引入numpy库
1 | import numpy as np |
将明文进行分组处理
1 | def process_text(init_message, group_len): |
拓展欧几里得算法
1 | def extended_gcd(a, b): |
求乘法逆元
1 | def modular_inverse_element(a: int, m=26): |
加密计算
1 | def polyalphabetic_substitution(code: list, A, B, m=26) -> list: |
矩阵的乘法逆元
1 | def modular_inverse_matrix(A, m=26): |
解密计算
1 | def inverse_polyalphabetic_substitution(code: list, inv_a, B, m=26) -> list: |
加密函数
1 | def encrypt_message(key_a, key_b, plaintext): |
解密函数
1 | def decrypt_message(key_a, key_b, ciphertext): |
实验测试
1 | if __name__ == '__main__': |
相关numpy库中函数的用法补充
numpy.mat( )
numpy.mat() 的主要作用是将输入解释为矩阵。与 numpy.array() 不同,numpy.mat() 会返回一个二维矩阵,而不是一个 n 维数组。
例如,如果你有一个列表 [1, 2, 3],你可以使用 numpy.mat() 将其转换为一个 1x3 的矩阵:
1 | import numpy as np |
运行上述代码,你会得到以下输出:
1 | [[1 2 3]] |
numop.dot( )
numpy.dot函数用于计算两个数组的点积(内积)。
点积是指两个数组的对应元素相乘后再求和的结果。它可以用于计算向量的长度、计算矩阵的乘法等。
numpy.dot函数的语法如下:
1 | numpy.dot(a, b, *out*=None) |
其中,a和b是要计算点积的两个数组,可以是一维数组、二维数组或多维数组。out参数是可选的,用于指定计算结果的输出数组。
以下是一些示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
result = np.dot(a, b)
print(result) # 输出:32
c = np.array([[1, 2], [3, 4]])
d = np.array([[5, 6], [7, 8]])
result = np.dot(c, d)
print(result) # 输出:[[19 22]
# [43 50]]
在这些示例中,np.dot(a, b)计算了一维数组a和b的点积,结果为32。np.dot(c, d)计算了二维数组c和d的点积,结果为一个二维数组.
numpy.reshape( )
numpy.reshape()函数用于改变数组的形状,即重新排列数组的维度。它接受一个数组作为输入,并返回一个具有新形状的数组,而不改变原始数组的数据。
numpy.reshape()函数的语法如下:
1 | numpy.reshape(array, newshape, order='C') |
参数说明:
- array:要改变形状的数组。
- newshape:新的形状,可以是一个整数或一个整数元组。
- order:可选参数,指定数组在内存中的存储顺序。默认为’C’,表示按行存储。
下面展示一些示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import numpy as np
# 创建一个一维数组
arr = np.array([1, 2, 3, 4, 5, 6])
# 将一维数组转换为二维数组
new_arr = np.reshape(arr, (2, 3))
print(new_arr)
# 输出:
# [[1 2 3]
# [4 5 6]]
# 创建一个二维数组
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
# 将二维数组转换为三维数组
new_arr2 = np.reshape(arr2, (2, 3, 1))
print(new_arr2)
# 输出:
# [[[1]
# [2]
# [3]]
#
# [[4]
# [5]
# [6]]]全部代码
1 | import numpy as np |