1、引例:仿射密码恢复明文
2.1 仿射密码:
AOPC GUDE YKRO IFKG BEFM CPIY CRAR DEPB AQUF EPGH KJPK DDCJ GKPJ IEVC GEBE BAYC
FAMC XCER IARE HAFF ERJG HCRA OKBB KYAR RCED KFAI GHCP CDCK DFCB KKME FEMC GKXC
OKRQ KYYE BKYC ERBH CCRJ KVEI BKPS AQKU FJRK BIDC EMEG HKFC ICRB CRQC ARQK YDER
SERJ GEIQ KRIA JCPC JRKB BKKX PAOH B答案:
2.1.密钥K=(a,b)=(19,4),明文为:
l grew up anong slow talkers,men in particular,who dropped words a few at a time like beansin a hill, and when I got to Minneapolis where people took a Lake Wobegon comma to mean theend of a story, I couldn't speak a whole sentence in company and was considered not too bright.So I enrolled in a speech course taught by Orville Sand, the founder of reflexive relaxology, aself-hypnotic technique that enabled a person to speak up to three hundred words per minute.
2、python代码实现(推荐)
# -*- coding: utf-8 -*-
'''
代码中各个函数的说明如下
gcd(a, b) #获取两个数的最大公因数
multi_gcd(num) #获取数组中所有数的最大公因数
find_substr(strs) #统计字符串中长度为2的子串出现的次数
cal_pos(substr, strs, count) #计算字符串中,子串出现位置的距离差
cal_frequency(strs) #统计字符串中,英文字符出现的频率,并计算出 M_n
str_offset(strs, n) #将字符串中的所有英文字符整体向左偏移n位
'''
import operator
from functools import reduce
c = "AOPCGUDEYKROIFKGBEFMCPIYCRARDEPB\
AQUFEPGHKJPKDDCJGKPJIEVCGEBEBAYC\
FAMCXCERIAREHAFFERJGHCRAOKBBKYAR\
RCEDKFAIGHCPCDCKDFCBKKMEFEMCGKXC\
OKRQKYYEBKYCERBHCCRJKVEIBKPSAQKU\
FJRKBIDCEMEGHKFCICRBCRQCARQKYDER\
SERJGEIQKRIAJCPCJRKBBKKXPAOHB"
C = []
def gcd(a, b):
return gcd(b,a%b) if b!=0 else a
def multi_gcd(num):
return reduce(gcd,num)
def find_substr(strs):
ans={}
for i in range(len(strs) - 1):
substr = strs[i:i + 1]
count=0
if substr not in ans.keys():
for j in range(len(strs) - 1):
if substr == strs[j:j + 1]:
count=count+1;
ans[substr] = count
return ans
def cal_pos(substr, strs, count):
ans = []
last_pos=0
for i in range(count):
temp=last_pos
last_pos = strs.find(substr, temp+1)
#print(last_pos)
if i != 0:
ans.append(last_pos - temp)
return ans
def cal_frequency(strs):
p = [0.082, 0.015, 0.028, 0.043, 0.127, 0.022, 0.02,
0.061, 0.07, 0.002, 0.008, 0.04, 0.024, 0.067,
0.075, 0.019, 0.001, 0.06, 0.063, 0.091, 0.028,
0.01, 0.023, 0.001, 0.02, 0.001]
frequency = [strs.count(chr(ord('A') + i)) for i in range(26)]
ans=sum((frequency[i]*p[i]/ len(strs)) for i in range(len(frequency)))
return ans
def str_offset(strs, n):
return "".join([chr((ord(i)-ord('A')-n)%26+ord('A'))for i in strs])
def crack(strs, dictionary):
dictionary=sorted(dictionary.items(), key=operator.itemgetter(1), reverse=True)
print(dictionary)
#encoding:utf-8
def NI(x,b): #定义求x关于b的逆元的函数NI,其中(NI(x,b)*x) mod b = 1 当x和b互质时求出的逆元唯一
i = 1
while (x*i)%b != 1:
i = i + 1
return i
#对密文进行预处理并储存在列表中,储存形式是对应字母在26个英文字母中的位序
for i in c:
if i == ' ':
C.append(i)
else:
C.append(ord(i)-65)
strs=c
dictionary = find_substr(strs)
print('dictionary data:', sorted(dictionary.items(), key=operator.itemgetter(1), reverse=True),'\n')
#将加密算法中a可能的取值储存在列表中
a = [3,5,7,9,11,15,17,19,21,23,25]
P = []
for keyb in range(0,26):
for keya in a:
y=ord(max(dictionary.items(),key=operator.itemgetter(1))[0])-ord('A')
x=ord('E')-ord('A')
ni_a = NI(keya,26)
if int((y-keyb)*ni_a)%26!=int(x):
continue
for s in C:
if s == ' ':
P.append(' ')
else:
P.append(((s-keyb)*ni_a)%26) #将明文字母对应的位次码依次加入到明文列表中
strP = ''
for t in P:
if t==' ':
strP = strP + ' '
else:
strP = strP + chr(t+97) #将明文转化为字符串并输出
print('keya:',keya,' keyb:',keyb,' strP:',strP)
P = []
3、求解答案
dictionary data: [('C', 26), ('K', 25), ('E', 21), ('R', 20), ('A', 14), ('B', 14), ('F', 11), ('P', 10), ('G', 10), ('I', 10), ('D', 9), ('J', 9), ('Y', 8), ('H', 7), ('Q', 6), ('O', 5), ('M', 5),
('U', 3), ('X', 3), ('V', 2), ('S', 2)]
keya: 7 keyb: 0 strP: acremotiwuvcqxumpixyerqwevavtirpagoxirmbufruttefmurfqidemipipawexayeheivqavibaxxivfmbevacuppuwavveituxaqmbereteutxepuuyixiyemuhecuvguwwipuweivpbeevfudiqpurkaguoxfvupqteiyimbuxeqevpevgeavguwtivkivfmiqguvqaferefvuppuuhracbp
keya: 19 keyb: 4 strP: ## 搜索 the 定位
igrewupamongslowtalkersmeninparticularwhodroppedwordsafewatatimelikebeansinahillandwhenigottominneapoliswherepeopletookalakewobegoncommatomeantheendofastoryicouldnotspeakawholesentenceincompanyandwasconsiderednottoobright
keya: 25 keyb: 6 strP: gsreamdciwpsybwafcbueryiepgpdcrfgqmbcrazwxrwddexawrxycleacfcfgiebguejecpygpczgbbcpxazepgswffwigppecdwbgyazeredewdbefwwucbcueawjeswpqwiicfwiecpfzeepxwlcyfwrogqwmbxpwfydecucazwbeyepfepqegpqwidcpocpxacyqwpygxerexpwffwwjrgszf
keya: 5 keyb: 8 strP: owrekszuyqhwapqkjupgerayehohzurjomspurkfqvrqzzevkqrvaunekujujoyepogedeuhaohufoppuhvkfehowqjjqyohheuzqpoakferezeqzpejqqgupugekqdewqhmqyyujqyeuhjfeehvqnuajqrcomqspvhqjazeugukfqpeaehjehmeohmqyzuhcuhvkuamqhaoverevhqjjqqdrowfj
keya: 11 keyb: 10 strP: syrecixqgadyojaclqjmerogedsdxqrlskijqrcvahraxxehcarhoqbecqlqlsgejsmeneqdosdqvsjjqdhcvedsyallagsddeqxajsocverexeaxjelaamqjqmecaneyadkaggqlageqdlveedhabqolarwskaijhdaloxeqmqcvajeoedledkesdkagxqdwqdhcqokadosherehdallaanrsyvl
keya: 17 keyb: 12 strP: kurescbyqglumvgshyvaermqelklbyrhkocvyrspgjrgbbejsgrjmyzesyhyhkqevkaeteylmklypkvvyljspelkughhgqklleybgvkmsperebegbvehggayvyaesgteuglogqqyhgqeylhpeeljgzymhgrikogcvjlghmbeyayspgvemelheloeklogqbyliyljsymoglmkjerejlghhggtrkuph
keya: 23 keyb: 14 strP: wareuyvmokzacdkunmdsercoezwzvmrnwiydmrulktrkvvetukrtcmpeumnmnwoedwsexemzcwzmlwddmztulezwaknnkowzzemvkdwculerevekvdenkksmdmseukxeakzikoomnkoemznleeztkpmcnkrqwikydtzkncvemsmulkdecezneziewzikovmzqmztumcikzcwteretzknnkkxrwaln
keya: 3 keyb: 16 strP: mireoknwuyjigfyovwfqerguejmjnwrvmakfwroxyprynnepoyrpgwteowvwvmuefmqelewjgmjwxmffwjpoxejmiyvvyumjjewnyfmgoxereneynfevyyqwfwqeoyleiyjayuuwvyuewjvxeejpytwgvyrsmaykfpjyvgnewqwoxyfegejvejaemjayunwjswjpowgayjgmperepjyvvyylrmixv
keya: 9 keyb: 18 strP: yoreqghkscxowncqbknierwsexyxhkrbyugnkrqtczrchhezqcrzwkjeqkbkbysenyiepekxwyxktynnkxzqtexyocbbcsyxxekhcnywqterehechnebcciknkieqcpeocxucsskbcsekxbteexzcjkwbcrayucgnzxcbwhekikqtcnewexbexueyxucshkxakxzqkwucxwyzerezxcbbccpryotb
keya: 15 keyb: 20 strP: qkregalscifkuzigxszwerucefqflsrxqyazsrgnibrillebgirbushegsxsxqcezqwevesfuqfsnqzzsfbgnefqkixxicqffeslizqugnereleilzexiiwszswegivekifyiccsxicesfxneefbihsuxirmqyiazbfixuleswsgnizeuefxefyeqfyiclsfmsfbgsuyifuqberebfixxiivrqknx
keya: 21 keyb: 22 strP: umreyqjoksbmitsyzotcerikebubjorzuwqtorydsnrsjjenysrnioveyozozuketucefeobiuboduttobnydebumszzskubbeojstuiyderejesjtezsscotoceysfemsbwskkozskeobzdeebnsvoizsrguwsqtnbszijeocoydsteiebzebweubwskjobgobnyoiwsbiunerenbszzssfrumdz
4、暴力破解(不推荐)
#encoding:utf-8
def NI(x,b): #定义求x关于b的逆元的函数NI,其中(NI(x,b)*x) mod b = 1 当x和b互质时求出的逆元唯一
i = 1
while (x*i)%b != 1:
i = i + 1
return i
c = "AOPCGUDEYKROIFKGBEFMCPIYCRARDEPBAQUFEPGHKJPKDDCJGKPJIEVCGEBEBAYCFAMCXCERIAREHAFFERJGHCRAOKBBKYARRCEDKFAI GHCP CDCK DFCB KKME FEMC GKXC OKRQ KYYE BKYC ERBH CCRJ KVEI BKPS AQKU FJRK BIDC EMEG HKFC ICRB CRQC ARQK YDER SERJ GEIQ KRIA JCPC JRKB BKKX PAOH B"
C = []
#对密文进行预处理并储存在列表中,储存形式是对应字母在26个英文字母中的位序
for i in c:
if i == ' ':
C.append(i)
else:
C.append(ord(i)-65)
#将加密算法中a可能的取值储存在列表中
a = [3,5,7,9,11,15,17,19,21,23,25]
P = []
for keyb in range(0,26):
for keya in a:
ni_a = NI(keya,26)
for s in C:
if s == ' ':
P.append(' ')
else:
P.append(((s-keyb)*ni_a)%26) #将明文字母对应的位次码依次加入到明文列表中
strP = ''
for t in P:
if t==' ':
strP = strP + ' '
else:
strP = strP + chr(t+97) #将明文转化为字符串并输出
print(strP)
print("==========================")
P = []
# AOPC GUDE YKRO IFKG BEFM CPIY CRAR DEPBAQUF EPGH KJPK DDCJ GKPJ IEVC GEBE BAYCFAMC XCER IARE HAFF ERJG HCRA OKBB KYARRCED KFAI GHCP CDCK DFCB KKME FEMC GKXCOKRQ KYYE BKYC ERBH CCRJ KVEI BKPS AQKUFJRK BIDC EMEG HKFC ICRB CRQC ARQK YDERSERJ GEIQ KRIA JCPC JRKB BKKX PAOH B
# 结果:
# i grew up among slow talkers men in particular who dropped word safe wata time like beans in a hill and when i got to minneapolis where people took a lake wobegon comma to mean the end of astory i could not speak a whole sentence in company and was considered not to obright
## 搜索the 得出结果