用Python解密替换密码
我知道之前有人问过类似的问题,但这个问题其实挺简单的。
我有一个用替换密码编码的文本文件,我需要用Python把它解码。可惜我没有任何正确解码的单词示例。这里的替换关系是一对一的,字母的大小写没有区别。而且标点符号没有改变,空格也保持原样。我不太需要代码方面的帮助,更想知道一般来说可以怎么做。我的主要思路有:
- 先解决1、2或3个字母的单词,这样可以缩小选择范围。
- 我可以使用不同长度的英语单词列表来进行对比。
- 我可以利用字母的频率分布来帮助解码。
有没有人能给我一些一般性的思路,帮我想想该怎么做呢?
3 个回答
你可以试试这个方法:
先准备一个有效单词的列表(就像字典一样),还有一个你所用语言的“正常”字母分布(可以用一个列表来表示)。
计算一下你那段乱七八糟的文字中各个字母的分布情况。
把你计算出来的字母分布和正常的字母分布进行比较,然后根据这个来调整你的文字。
重复这个过程:创建一个数组(排名),包含26个字母,初始值都设为0.0(比如:rank('A')=rank('B')=...=rank('Z')=0.0)。
检查你生成的文字中的单词,看看哪些在字典里。如果某个单词在字典中,就把这个单词的字母的排名提高(可以加一个标准值,比如1.0)。换句话说,就是计算得分(得分是总排名和字典中单词数量的函数)。
如果得分足够高,就把这个文本保存到高分表里。
如果所有单词都在字典里,或者总排名足够高,或者这个循环执行超过10000次,就结束。
如果还没结束,就随机选择两个字母,交换它们的位置。但要注意,排名高的字母被交换的机会要少一些。
继续重复这个过程。
最后:打印出高分的文本。
这个过程有点像模拟退火。
我首先会找一份英语单词的参考列表。接下来,构建一个可能的2个字母和3个字母单词的列表。然后就开始在你的密码中测试这些小单词。一旦你猜出一个小单词,就用你的单词列表检查更大的单词。如果有些单词在列表中没有可能的完成形式,那你就走错方向了。如果一个单词只有一个可能的完成形式,就接受它是正确的,然后继续。最终,你要么会找到一个所有单词都在你的英语单词列表中的解决方案,要么会发现某个单词没有解决方案。
我写了一个东西,用来处理Haley说话时的乱码。这个东西并不是自动生成的,而是根据“etaoinshrdlu”这个顺序来猜测的(这是英语中使用频率最高的字母,从多到少排列),同时允许用户手动调整每个加密字母的意思。
所以它会显示类似这样的内容:
t0is is a 12eat 34556e!
然后你需要手动猜测每个数字代表哪个字母,直到你能读懂为止。
这种方法的好处是它能容忍一些拼写错误。如果你的加密工具出错了(或者在明文中使用了字典里没有的单词),你可能会遇到无法解决的难题。
不过,拼写检查工具有很好的英语单词列表。我在我的猜单词游戏解答器中使用了Debian的dictionaries-common包里的那个列表。