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 得出結果