2013-12-03 49 views
4

我正在使用python构建一个凯撒密码解密器,它的工作原理和解密已加密的单词。然而,它显示了所有的蛮力解密尝试,例如,用你的密钥3加密的“HELLO”是KHOOR。解密后的结果是“KHOORJGNNQIFMMPHELLOGDKKNFCJJMEBIILDAHHKCZGGJBYFFIAXEEHZWDDGYVCCFXUBBEWTAADVSZZCURYYBTQXXASPWWZROVVYQNUUXPMTTWOLSSVNKRRUMJQQTLIPPS”我想知道是否有使用字典与Python在此输出来搜索英文单词的方式或能提高我的代码,只打印出已知的英语单词。如果以前有人问过这个问题,我抱歉,我四处搜寻,似乎找不到正确的东西。在无间隔段落中查找单词?

+2

看起来好像字母频率会很有帮助,还有字母对频率 –

+1

@JoranBeasley说什么是替代密码的密码分析的标准方法。安德鲁,你应该坚持。 – Hyperboreus

+0

请参阅编辑我的答案。我已经使用频率实现了一种天真的方法。 – Hyperboreus

回答

4
englishWords = ['HELLO', 'ME', 'AXE', 'FOO', 'BAR', 'BAZ'] #and many more 
cypher = 'KHOORJGNNQIFMMPHELLOGDKKNFCJJMEBIILDAHHKCZGGJBYFFIAXEEHZWDDGYVCCFXUBBEWTAADVSZZCURYYBTQXXASPWWZROVVYQNUUXPMTTWOLSSVNKRRUMJQQTLIPPS' 

for word in englishWords: 
    if word not in cypher: continue 
    print('Found "{}"'.format(word)) 

这产生了:

Found "HELLO" 
Found "ME" 
Found "AXE" 

如果这是关于看,如果decyphering文本的关键是正确的,也就是说,如果结果可能为英文单词,我不会找单词,但试图在结果中找到不符合英语音节的群集。


这里的字母频率很天真的实现扫描:

#! /usr/bin/python3 

plain = 'Z RD NFEUVIZEX ZW KYVIV ZJ R NRP KF LJV R UZTKZFERIP NZKY GPKYFE KF JVRITY WFI RE VEXCZJY NFIU ZE KYZJ FLKGLK FI TRE Z ZDGIFMV DP TFUV KF FECP GIZEK FLK BEFNE VEXCZJY NFIUJ. RGFCFXZVJ ZW KYZJ YRJ SVVE RJBVU SVWFIV, Z JVRITYVU RIFLEU REU TFLCUE\'K JVVD KF WZEU KYV IZXYK KYZEX.'.upper() 

freqs = {'E': 12.7, 'T': 9.1, 'A': 8.2, 'O': 7.5, 'I': 7.0} 

def cypher(text, key): 
    return ''.join(chr((ord(c) - ord('A') + key) % 26 + ord('A')) if 'A' <= c <= 'Z' else c for c in text) 


def crack(text): 
    length = len(text) 
    best = 100000 
    bestMatch = '' 
    for key in range(26): 
     cand = cypher(text, key) 
     quality = 0 
     for l, c in {letter: sum(1 for c in cand if c == letter) for letter in 'ETAOI'}.items(): 
      quality += (c/length - freqs[l]) ** 2 
     if quality < best: 
      best = quality 
      bestMatch = cand 
    return bestMatch 

print(crack(plain)) 

以下三个例子:

Input: TQ ESTD TD LMZFE DPPTYR, TQ ESP VPJ QZC OPNJASPCTYR L EPIE TD ESP NZCCPNE ZYP, T.P. TQ ESP CPDFWE XTRSE MP PYRWTDS HZCOD, T HZFWOY'E WZZV QZC HZCOD, MFE ECJ EZ QTYO NWFDEPCD TYDTOP ESP CPDFWE HSTNS OZ YZE NZXAWJ HTES ESP PYRWTDS DJWWLMWP LALCEFD. 

Output: IF THIS IS ABOUT SEEING, IF THE KEY FOR DECYPHERING A TEXT IS THE CORRECT ONE, I.E. IF THE RESULT MIGHT BE ENGLISH WORDS, I WOULDN'T LOOK FOR WORDS, BUT TRY TO FIND CLUSTERS INSIDE THE RESULT WHICH DO NOT COMPLY WITH THE ENGLISH SYLLABLE APARTUS. 

Input: KWSJUZAFY XGJ WFYDAKZ OGJVK AF S TDGUC GX MFVAXXWJWFLASLWV LWPL DACW LZSL AK UWJLSAFDQ HGKKATDW, SFV VGAFY AL WXXAUAWFLDQ AK S YWFMAFWDQ AFLWJWKLAFY HJGTDWE. TML AL'K HJGTDWESLAU XGJ DGLK GX JWSKGFK, BMKL GFW GX OZAUZ AK LZSL QGMJ WFUJQHLWV LWPL ESQ AFUDMVW LWPL LZSL JSFVGEDQ ZSHHWFK LG XGJE SF WFYDAKZ OGJV UGEHDWLWDQ TQ UZSFUW. 

Output: SEARCHING FOR ENGLISH WORDS IN A BLOCK OF UNDIFFERENTIATED TEXT LIKE THAT IS CERTAINLY POSSIBLE, AND DOING IT EFFICIENTLY IS A GENUINELY INTERESTING PROBLEM. BUT IT'S PROBLEMATIC FOR LOTS OF REASONS, JUST ONE OF WHICH IS THAT YOUR ENCRYPTED TEXT MAY INCLUDE TEXT THAT RANDOMLY HAPPENS TO FORM AN ENGLISH WORD COMPLETELY BY CHANCE. 

Input: QZC PILXAWP, UFDE ESP EPIE JZF'GP AZDEPO SPCP TYNWFOPD SPWW, TQ, WTA, WZR, LDA LYO ACZMLMWJ ZESPCD. JZF NZFWO ECTX OZHY ESP LWEPCYLETGPD MJ ZYWJ DPLCNSTYR QZC HZCOD ESP DLXP WPYRES LD JZFC ELCRPE HZCO, LYO ZYWJ QZC HZCOD HTES ESP DLXP WPEEPC ALEEPCY. MFE ESLE'D CPLWWJ BFTEP L WZE ZQ HZCV EZ RPE LCZFYO ESP QLNE ESLE JZFC TYTETLW ZFEAFE SLD L WZE ZQ FDPWPDD OLEL TY TE. 

Output: FOR EXAMPLE, JUST THE TEXT YOU'VE POSTED HERE INCLUDES HELL, IF, LIP, LOG, ASP AND PROBABLY OTHERS. YOU COULD TRIM DOWN THE ALTERNATIVES BY ONLY SEARCHING FOR WORDS THE SAME LENGTH AS YOUR TARGET WORD, AND ONLY FOR WORDS WITH THE SAME LETTER PATTERN. BUT THAT'S REALLY QUITE A LOT OF WORK TO GET AROUND THE FACT THAT YOUR INITIAL OUTPUT HAS A LOT OF USELESS DATA IN IT. 

在这里,没有空格和标点的最后一个例子:

Input: ZRDLJZEXGPKYFEKFSLZCURTRVJRITZGYVIUVTIPGKVIZKNFIBJREUUVTIPGKJKYVRCIVRUPVETIPGKVUNFIUYFNVMVIZKJYFNJRCCZKJ SILKVWFITVUVTIPGKZFERKKVDGKJWFIVORDGCVYVCCFVETIPGKVUNZKYRBVPFW3ZJBYFFI 

Output: IAMUSINGPYTHONTOBUILDACAESARCIPHERDECRYPTERITWORKSANDDECRYPTSTHEALREADYENCRYPTEDWORDHOWEVERITSHOWSALLITS BRUTEFORCEDECRYPTIONATTEMPTSFOREXAMPLEHELLOENCRYPTEDWITHAKEYOF3ISKHOOR 
+0

我加了一些例子。 – Hyperboreus

3

像这样在一块无差别的文本中搜索英文单词当然是可能的,并且高效地执行它是一个真正有趣的问题。但由于很多原因,这是有问题的,其中一个原因是您的加密文本可能包含随机发生的偶然形成英文单词的文本。

例如,只有你在这里张贴的文本包括HELLIFLIPLOGASP和可能其他人。您只需搜索与您的目标词相同长度的词,并且仅限于具有相同字母模式的词,才可以减少替代方法。但是为了解决这个事实,你的初始输出中有很多无用的数据,这确实是相当多的工作。在从行字典文件

  1. 阅读(/usr/share/dict/words在大多数系统上):

    你可以很容易地检查,找出一个特定的词是否在通过这样一本英语词典。

  2. 删除空格,转换为小写并将每行存储在Python字典中。
  3. 解密每个单词后,检查它是否作为Python词典中的键存在。

采取这种方法可能比试图通过未分配的初始输出进行拼凑更有意义。

+0

解决该问题(处理数据段而不是单个单词时)的方法是根据字符总数要求最少数量的匹配。 – Razick