单表代替密码
仿射密码
仿射密码为单表代替密码,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()