用暴力破解凯撒密码

Breaking the Caesar Cipher with brute force

前两个函数是我的:

def rotated(n: int):
    '''Returns a rotated letter if parameter is greater than 26'''
    ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
    if n >= 26:
        n %= 26
    return ALPHABET[n:26] + ALPHABET[:n]
assert rotated(0) == 'abcdefghijklmnopqrstuvwxyz'
assert rotated(26) == 'abcdefghijklmnopqrstuvwxyz'

def Caesar_decrypt(text: str, key: int) -> str:
    '''Returns a decryption of parameter text and key''' 
    text = text.lower()
    key_to_zero = str.maketrans(rotated(key),rotated(0))
    return text.translate(key_to_zero)

但是我的搭档负责第三个功能:

def Caesar_break(code: str)-> str:
    'Decrypts the coded text without a key'
    file = open('wordlist.txt', 'r')
    dic = []
    dlist = file.readlines()
    wl = []
    l = []
    cl = []
    swl = []
    sw = ''
    for words in code:
        if words.isalnum() or words.isspace():
            l.append(words)
        else:
            l.append(' ')
    Ncode = ''.join(l)
    codelist = Ncode.split()

    high = 0
    for i in range(1,27):
        highesthit = 0
        hit = 0
        out = Caesar_decrypt(Ncode, i)
        e = 0
        l = 0
        while l < len(dlist):
            dic.append(dlist[l].split()[0])
            l += 1
        while e < len(dic):
            if out == dic[e]: 
                hit += 1
                e += 1
        if hit > highesthit:
                high = i
                highesthit = hit
    return(Caesar_decrypt(Ncode, high))

我现在联系不上他,所以我想知道是否有更简单的方法来使用暴力破解凯撒密码。我的伙伴在他的代码中使用了太多的随机字母,所以我真的看不懂。

注意:"wordlist.txt"是我们下载下来的文档,里面有字典里的所有单词。 Here是link供参考。

Caesar_break 代码应该像这样工作:

Caesar_break('amknsrcp qagclac') == 'computer science'

如果您确定密文是用 ceaser (x+3)mod25 加密的,您可以只浮动字母。我会先将所有文本设为小写。然后获取所有字符的 asci 值。比如asci(a)=97,让97-97=0;对于 b 使其成为 98-97=1.Then 我会制作 2 个数组,1 个用于字符,1 个用于字符的整数值....

代码破解!耶!破解凯撒密码的最简单方法是假设您的编码文本在字母频率方面代表了它所使用的实际语言。在英语中,相对频率看起来有点像:

"etaoinshrdlcumwfgypbvkjxqz"
# most to least common characters in English according to
# https://en.wikipedia.org/wiki/Letter_frequency

然后,破解凯撒密码的最快方法是在加密短语中创建一个 collections.Counter 字母,找到最常见的一对,并假设每个字母(依次)是 e。从那里计算你的差异,并应用解密密码。测试一下是不是有效的英文,哒哒!

import collections

def difference(a: str, b: str) -> int:
    a, b = a.lower(), b.lower()
    return ord(b) - ord(a)

def english_test(wordlist: "sequence of valid english words",
                 text: str) -> bool:
    """english_test checks that every word in `text` is in `wordlist`"""
    return all(word in wordlist for word in text)

def bruteforce_caeser(text: str) -> str:
    with open('path/to/wordlist.txt') as words:
        wordlist = {word.strip() for word in words}
        # set comprehension!
    c = collections.Counter(filter(lambda ch: not ch.isspace(), text))
    most_common = c.most_common()  # ordered by most -> least common
    for ch, _ in most_common:
        diff = difference('e', ch)
        plaintext = Caeser_decrypt(text, diff)
        if english_test(wordlist, plaintext):
            return plaintext

虽然此代码中存在细微的逻辑错误,w.r.t。关于输入文本的假设。我将把它作为练习留给学生,让他们找出逻辑错误,并思考可以进行哪些小改动以确保任何输入的结果。作为提示:尝试旋转然后解密以下短语:

Judy I don't think it's right for you to contact such a marksman as this man, for without warning this marksman could shoot and kill you.