Python:解码用仿射密码编码的 Vigenere 密码

问题描述

我如何解码一些像这样编码的文本:affine(vigenere(text,vigenere_key),*affine_key)?我不知道其中任何一个的钥匙。起初我以为我可以通过尝试所有可能的组合来暴力破解它,但后来我意识到破解 Vigenere 是基于找到关键字,它实际上可以是任何东西,因为在破解 Vigenere 后解码的消息没有任何意义,因为它仍然是编码的使用 Affine 我有点困惑,我该如何找到正确的 Vigenere 钥匙并破解它?

解决方法

好吧,我想这不会回答您的问题,但我希望它能有所帮助。在你的情况下,如果你真的想破解这个密文,你可以尝试暴力破解仿射密码密钥(我希望它不会很长,因为暴力破解具有指数时间复杂度)然后对于每个解密的密文,你可以测试该特定的解密密文是否具有通过利用vignere cipher的特性增加了一层vigenere加密保留明文语言重合索引的痕迹,可以用来猜测那段解密的密文是否有点像英语(除了字母是替换)虽然这仅在 vigenere 键很短(大约 5 或 6 个字符)时才有效。那么在有了一个有前途的候选人之后,你可以使用蛮力来破解 vigenere 密钥。

此python代码计算巧合指数并尝试猜测密钥长度

def index_of_coincidence(ciphertext: str) -> float:
    alphabet = "qwertyuioplkjhgfdsazxcvbnm"
    ciphertext = ciphertext.lower()
    ciphertext_length = 0

    for char in ciphertext:
        if char in alphabet:
            ciphertext_length += 1

    lc = 0
    denomiator = (ciphertext_length * (ciphertext_length-1))
    for char in alphabet:
        letter_count = ciphertext.count(char)
        lc += (letter_count * (letter_count-1)) / denomiator
    return lc

def vigenere_key_length(ciphertext: str) -> int:

    lc_ranges = ["x",0.0639,0.0511,0.0468,0.0446,0.0438,0.0426]
    lc = index_of_coincidence(ciphertext)

    print(lc)
    if lc >= lc_ranges[1]:
        print("The Key length is probably {}".format(1))
        key = 1
        return key

    key = 1
    for key_length in range(1,6):
        if key_length == 6:
            print("Cant determine Key length with accuracy")
            return None
            
        if lc_ranges[key_length] >= lc >= lc_ranges[key_length + 1]:
            key += key_length
            break

    print("The Key Length is probably {}".format(key))
    return key

请注意,对于较小的密钥长度,破解 vigenere 密钥的预期时间复杂度不会很大,例如 5 个字符的密钥长度将是 7893600 = 26*25*24*23*22 次尝试,这对于每个解密的密文,但如果仿射密钥很大,它会变得复杂,最好在暴力破解之前使用上面的代码来测试它是否可能是英文候选。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...