Python:解码使用仿射密码编码的 Vigenere 密码
Posted
技术标签:
【中文标题】Python:解码使用仿射密码编码的 Vigenere 密码【英文标题】:Python: decode Vigenere cipher that was encoded with Affine cipher 【发布时间】:2021-04-15 00:26:05 【问题描述】:如何解码一些像这样编码的文本:affine(vigenere(text, vigenere_key), *affine_key)
?我不知道其中任何一个的钥匙。起初我以为我可以通过尝试所有可能的组合来暴力破解它,但后来我意识到破解 Vigenere 是基于找到可以是字面上任何东西的关键字,因为在破解 Vigenere 后解码的消息没有任何意义,因为它仍然是编码的使用 Affine 我有点困惑如何找到 Vigenere 的正确密钥并破解它?
【问题讨论】:
【参考方案1】:好吧,我想这不会回答您的问题,但我希望它可以提供帮助。在您的情况下,如果您认真对待破解此密文,您可以尝试强制仿射密码密钥(我希望它不会很长时间,因为暴力破解具有指数时间复杂度)然后对于每个解密的密文,您可以测试该特定解密密文是否具有通过利用 vignere cipher 的特性,额外增加一层 vigenere 加密,保留明文语言的 Index of巧合 的痕迹,可以用来猜测那段解密的密文是否有点像英语(除了字母是替换)虽然这只能在 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
尝试,这对于每个解密的密文都可以轻松完成,但是如果仿射密码密钥很大,它会变得很复杂,最好使用上面的代码在暴力破解之前测试它是否是可能的英语候选者。
【讨论】:
以上是关于Python:解码使用仿射密码编码的 Vigenere 密码的主要内容,如果未能解决你的问题,请参考以下文章