单表代替密码
仿射密码
仿射密码为单表代替密码,26个字母对应不同的数值,简单来说就是加法密码和乘法密码的结合,当下面式子中的a=1时就是凯撒密码了
A | B | C | D | E | F | G | H | I | J | K | L | M |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
密码体制的五元组:{P、C、K、E、D}
对于仿射密码而言:
\[
P=C=Z_{26}
\]
\[ K=\{(a,b) \in Z_{26}\times Z_{26}:gcd(a,26)=1\} \]
对于任意的\(k=(a,b) \in K,X,Y \in Z_{26}\)
\[ 加密:e_{k}(X)=(aX+b) \quad mod \quad 26 \]
\[ 解密:d_{k}(Y)=a^{-1}(Y-b) \quad mod \quad 26 \]
其中\(a^-1\)是a关于模26乘法的逆,即\(a \times b \quad mod \quad 26=1\)
实例
K=(3,7),加密"You are beautiful"
# encoding="utf-8" # @yoloyanng #求乘法逆元 def get(a,b): if b==0: return 1,0 else: k=a//b remainder = a % b x1,y1=get(b,remainder) x,y=y1,x1-k*y1 return x,y #加密函数 def encrypt(str1,a,b): private_data="" for i in str1: if(ord(i)>=97 and ord(i)<=122): cipher=((ord(i)-97)*a+b)%26 i=chr(cipher+97) elif(ord(i)>=65 and ord(i)<=90): cipher=((ord(i)-65)*a+b)%26 i=chr(cipher+65) else: i=i private_data+=i return private_data #解密函数 def decrypt(str2,a_1,b): public_data="" for i in str2: if(ord(i)>=97 and ord(i)<=122): temp = a_1*(ord(i)-97-b) % 26 i=chr(temp+97) elif(ord(i)>=65 and ord(i)<=90): temp = a_1*(ord(i)-65-b) % 26 i=chr(temp+65) else: i=i public_data+=i return public_data if __name__ == '__main__': a=5 b=8 a_1,y=get(a,26) str1="You are beautiful" miwen=encrypt(str1,a,b) mingwen=decrypt(miwen,a_1,b) print(miwen) print(mingwen)
多表代替密码
希尔密码
对于密码体制的五元组(P、C、K、E、D)有
\(P=C=(Z_{26})^m\),m是一个不小于2的整数
K是定义在\(Z_{26}\)上的\(m \times m\)可逆矩阵的集合,且集合中的元素的行列式与26互素
取密钥\(k \in K\),k为一个\(m \times m\)矩阵,记为\((k_{ij})\),对:
\[ x=(x_1,x_2,···,x_m) \in P,y=(y_1,y_2,···,y_m) \in C \]
定义:
\[ 加密:e_k(x)=k\times x \quad mod \quad 26 \]\[ 解密:d_k(y)=k^{-1} \times y\quad mod \quad 26 \]
\(k^{-1}\)为k的逆矩阵
实例
明文:yoloyanng
加密
将明文分成三个字母组成的分组 yol oya nng
,得到
\[
x_1=(24,14,11)^ T、x_2=(14,24,0)^T、x_3=(13,13,6)^T
\]
所以:
\[
(y_1,y_2,y_3)=(x_1,x_2,x_3) \times k
\]
即:
\[
y_1= k\times x_1=(7,15,11)^T、y_2= k \times x_2 =(20,24,6)^T、y_3=k \times x_3=(23,20,11)^T
\]
所以得到密文为:hpluygxul
解密
计算k
的模逆矩阵与密文相乘即可得到密文,具体略
Python:
import numpy as np from libnum import * # 转换为对应数字 def transform(string, size): string = string.lower() blocks = [string[i:i + size] for i in range(0, len(string), size)] # 将 a-z 编码为 0-25 temp = np.mat([list(map(ord, block)) for block in blocks]) - ord('a') return temp % 26 # 加密 def Encrypt(m, k, size): # 加密矩阵 c = "" m_num = transform(m, size) temp = [(np.dot(k, i.T) % 26) for i in m_num] for j in temp: for t in range(3): c = c + chr(j[t, 0] + ord('a')) return c # 解密 def Decrypt(c, k, size): m = "" # 计算行列式 detk = np.linalg.det(k) # 计算逆矩阵 k_inv = np.linalg.inv(k) # 求伴随矩阵 k_con = detk * k_inv % 26 k_1 = invmod(round(detk), 26) * k_con % 26 c_num = transform(c, size) temp = [(np.dot(k_1, i.T) % 26) for i in c_num] for j in temp: for t in range(3): m = m + chr(int(round(j[t, 0])) + ord('a')) return m if __name__ == '__main__': main()
维吉尼亚密码
对于密码体制的五元组(P、C、K、E、D)有
\(P=C=K=(Z_{26})^m\),m是一个正整数
对于任意的\(k=(k_1,k_2,······,k_m) \in K,x=(x_1,x_2,······,x_m) \in P,y=(y_1,y_2,······y_m) \in C\),
定义:
\[ 加密:e_k(x)=(x_1+k_1,x_2+k_2,···,x_m+k_m) \]\[ 解密:d_k(y)=(y_1-k_1,y_2-k_2,···,y_m-k_m) \]
以上的运算均在\(Z_{26}\)上运行(模26)
实例
m=6,密钥字:cipher,明文:it is always a good time
对应的关系如下:
it is always a good time ci ph erciph e rcip herc
# 维吉尼亚密码 # 加密 def Encrypt(key,plaintext,ascii): keylen=len(key) ptlen=len(plaintext) ciphertext ='' i = 0 while i < ptlen: j = i % keylen k = ascii.index(key[j]) m = ascii.index(plaintext[i]) ciphertext += ascii[(m+k)%26] i +=1 return ciphertext # 解密 def Decrypt(key,ciphertext,ascii): keylen=len(key) ctlen=len(ciphertext) plaintext ='' i =0 while i < ctlen: j = i % keylen k = ascii.index(key[j]) m = ascii.index(ciphertext[i]) if m < k: m +=26 plaintext += ascii[m-k] i +=1 return plaintext if __name__ == '__main__': ascii='abcdefghijklmnopqrstuvwxyz' key=input().lower()