文章目录
- 一、题目
- 二、古典密码
- [1]. 移位密码
- [2]. 仿射变换
- 三、代码
一、题目
通过编程对古典密码进行解密:
1.使用穷尽密钥搜索法,破译如下利用移位密码加密的密文:BEEAKFYDJXUQYHYJIQRYHTYJIQFBQDUYJIIKFUHCQD
;2.设有仿射变换对一个明文加密得到的密文为:
EDSGICKXHUKLZVEQZVKXWKZUKCVUH
又已知明文的前两个字符是“IF”。对该密文解密。
二、古典密码
[1]. 移位密码
在进行移位密码时,有26种移位的方法,类似于凯撒加解密。
由于字母只有26
个,所以密钥只能在[1,26]
范围内
假设密钥为3
、明文为A
时,加密就是使A
向右移动3
位,密文为D
。
将密文D
进行解密时,则需要使用密钥3
向左移动3
位,才能变回明文A
[2]. 仿射变换
进行仿射变换时,需要传入两个密钥
a和b
,字母也需要转换成数字,才能带入公式加密
字母转数字的规则:字母在字母表中的位置,且初始位置为0
,即[A,Z]
或[a,z]
为[0,25]
加密公式:c = (a * m + b) mod 26
解密公式:m = ((a^-1)*(c-b)) mod 26
参数 | 介绍 |
a | 密钥,a为整数,a与26互为素数,且范围在[0,25] |
b | 密钥,b为整数,且范围在[0,25] |
c | 密文,c为整数,且范围在[0,25] |
m | 明文,m为整数,且范围在[0,25] |
a-1 | a的逆元 |
mod | 即求余运算% |
在求解密钥a和b时,需要两个已知的密文c1、c2和两个对应的明文m1、m2
然后根据加密公式可以列出两个对应的方程式,联合求解
在编程中可以使用双循环,外循环a从0遍历到25,内循环b从0遍历到25
当a和b的值同时满足m1、m2加密后值为c1、c2时,就表明找到了密钥a、密钥ba的逆元求解时,a和a的逆元满足公式:a-1 * a = 1 mod 26
例题:求解9-1*(4-10)%26的值(相当于解密公式的**a=9、c=4、b=10**时,求解m)
解:
在计算时需要先求解9-1%26中的9-1,即求解一个值x,使( x9 )mod 26= 1即可。
通过一个个列举x的值,可以发现当x=3时,可以使式子( 39 )mod26=1
所以9的逆元为3
此时原式
= (3*(4-10))%26
= -18%26
= 8
三、代码
移位密码解密
仿射变换解密
# coding=utf-8
# 作者:小狐狸
# 题目:古典密码
def menu():
'''
菜单界面
'''
print("-----------------------")
print("| 0. 退出 |")
print("| 1. 移位密码解密 |")
print("| 2. 仿射变换解密 |")
print("-----------------------")
##menu() #测试函数
def yiwei(string,number):
'''
将字符串的每个字母,向右移动指定的位数,并返回移动后的字符串
如:A 向右移动3位,返回值为D
string为字符串,number为整型
A的ASCII码为65
'''
new_string = ""
string = string.upper() #转换为大写
for i in string: #移位操作
#转换为ascii码后,经过移位变为新的ascii,再转换回字母
new_string += chr((ord(i)-65+number)%26+65)
return new_string
##print(yiwei('AAA',3)) #测试函数正确性
def yiwei_decode(c):
'''移位密码解密,并打印解密的结果'''
for i in range(1,27): #穷尽密钥搜索,遍历范围[1,26]
print(yiwei(c,i))
print("解密结束")
##yiwei_decode("A") #测试函数正确性
def fangshe_key(m,c):
'''
通过已知的两对明文密文,求解得到两个密钥
m为明文,c为密文
[A-Z]转换为数字为[0-25]
'''
#大写
m = m.upper()
c = c.upper()
#切片
m1 = m[:1:] #明文的第一个字母
m2 = m[-1::] #明文的最后一个字母
c1 = c[:1:] #密文的第一个字母
c2 = c[-1::] #密文的最后一个字母
## print(m1,m2)
## print(c1,c2)
#转换为整数
m1 = ord(m1)-65
m2 = ord(m2)-65
c1 = ord(c1)-65
c2 = ord(c2)-65
## print(m1,m2)
## print(c1,c2)
#穷举法
for i in range(0,26):
for j in range(0,26):
if (m1*i+j)%26==c1 and (m2*i+j)%26==c2: #同时满足加密算法时
return i,j
return False
##print(fangshe_key("IF","ED")) #测试函数正确性
def fangshe_reverse(x,y):
'''
计算乘法逆元,求解x^-1(%y)的乘法逆元,并返回对应值
'''
i = 0
while True:
if x*i%26==1: #符合乘法逆元条件时
return i
i += 1
##print(fangshe_reverse(9,26)) #测试函数正确性
def fangshe_decode(c,a,b):
'''
仿射变换解密,并打印解密的结果
c为密文,a和b为密钥
0<=a,b<=25,且满足gcd(a,26)=1,a^-1表示a的逆元
加密公式:c = a*m + b%26
解密公式:m = (a^-1)*(c-b)%26
'''
new_string = ''
c = c.upper() #大写转换
for i in c: #逐个字母解密
new_i = ord(i)-65 #转换成数字
new_i = (fangshe_reverse(a,26)*(new_i - b))%26 #解密
new_string += chr(new_i + 65) #转换回大写字母
print(new_string)
print("解密结束")
##fangshe_decode("ED",9,10) #测试函数正确性
if __name__=='__main__':
while True:
menu()
choose = int(input("请选择: "))
if choose==1:
string = input("请输入密文: ")
yiwei_decode(string)
elif choose==2:
string = input("请输入密文: ")
m = input("已知明文:")
c = input("对应密文:")
a,b = fangshe_key(m,c)
fangshe_decode(string,a,b)
else:
break