【问题标题】:Which algorithms most reliably solve substitution ciphers?哪种算法最可靠地解决替换密码?
【发布时间】:2020-03-12 20:14:30
【问题描述】:

我正在研究一个问题,该问题简化为对用已知语言编写的冗长单字母替换密文的密码分析。如 Sinkov 的基本密码分析所述,这个问题很容易通过频率分析和单词模式手动解决。我很难找到一个理论上有效的算法:Joux 的 算法密码分析 甚至没有涵盖这种基本的替换,而且我从 Gaines 的 密码分析:密码及其研究的研究中一无所获解决方案(我应该查看哪些其他资源?)。

有些方法很明显。依次决定每个替换,然后利用已知的,只有在过程中没有出错的情况下才有效。采用元启发式优化——例如,重新分配字母直到找到的有效单词数量最大化——使得很难判断搜索何时结束。也许测试变化的动态编程方法是最好的。或者,this question 的答案包含其他可能幼稚的方法。

解决这类问题的首选算法是什么?

【问题讨论】:

    标签: algorithm nlp frequency-analysis linguistics cryptanalysis


    【解决方案1】:

    独立字母模型的精确最大似然估计

    如果我们假设(不切实际地)给定语言中的每个字母都以某个已知概率出现,独立于附近的字母,那么可以相当有效地找到确切的maximum likelihood estimate。这是您使用此模型所能期望的最好结果。

    假设消息中有 n 个字母,字母表中有 k 个字母。

    基本思想是,我们以某种方式为每个 k^2 个可能的字母对得出一个数字分数,然后在两个字母表上寻找最大权重的二分完美matching——也就是说,我们选择成对的字母,使一个字母表中的每个字母都与另一个字母表中的一个字母完全配对,并使所选对的分数总和最大化。有两个主要问题:(1)如何定义给定对的分数; (2) 一旦我们确定了个体分数,如何解决寻找对的最高和子集的一般问题。

    计分对

    编码后的字母x与源字母y的配对分数应该是log(p(y)^freq(x)),其中p(y)是字母y在语言中的已知概率,freq( x) 是字母 x 在编码输入中出现的次数。为什么?因为在这个忽略邻近字符影响的源语言简单模型下,生成任何给定的 n 个字符的源语言字符串的概率等于其中出现的字母概率的乘积,你也可以计算为 p(y)^freq(y) 对源字母表中所有字母 y 的乘积。因此,为了计算生成该字符串的概率,假设每个 x “真的”是一个 y(没有其他东西是一个 y),我们将 freq(y) 更改为 freq(x)。如果我们然后取日志,我们得到的是源字母表中所有字母 y 的 log(p(y)^freq(x)) 的 sum - 这个总和正是最大值二分完美匹配算法将最大化。

    寻找最佳完美匹配

    有一些算法可以在 O(V^2E) 时间内解决密切相关的maximum-weight bipartite matching problem,这里相当于 O(k^4) 时间。这个版本的问题看起来最大化所有选择对的总和,同时遵守没有项目与另一个集合中的两个或多个其他项目匹配的约束,但不要求每个项目都与其他项目匹配。幸运的是,我们可以通过在每个分数上添加一个大数 M 将这个算法变成一个非常简单地解决我们想要解决的“完美”变化的算法:直观地说,这会导致算法尝试添加尽可能多的边(因为即使省略一条边也有很大的成本,使得这样的解决方案甚至比包含全套 k 边的“愚蠢”解决方案差得多),同时仍然迫使算法在所有 k 边解决方案中选择最好的(因为所有这些解决方案都包含来自添加的权重的相同 kM 贡献)。

    【讨论】:

    • 谢谢!这种天真的方法可能会奏效,但我还不明白为什么它是最佳选择。不会有更多的上下文感知系统,例如基于 digrams 或 word patterns,在不寻常的输入上更准确?
    • 当然会,但你可以很容易地近似,例如通过将输入分解为不重叠的字母对,有效地将字母更改为 26*26=676 的大小之一。这会丢弃一半对中的信息(从偶数位置开始的那些),但如果您有大量数据,这无关紧要。
    • 如果您准备假设输入绝对是合法单词的序列,另一种方法是探索一棵树,其中第一个节点有 26 个子节点,对应于映射的所有可能方式源字母的第一个代码字母;每个孩子有 25 个孩子,对应于将不同于第一个(通常是第二个)的下一个代码字母映射到一个源字母的方式,该源字母产生一个 2 字符字符串,该字符串是一些合法单词序列的前缀;等树的深度等于不同代码字母的数量;你正试图到达一片叶子。
    【解决方案2】:

    This paper 描述了一种算法来解决同音替换密码,其中长度为 26 (a-z) 的字母表是一种特殊情况。他们在 C++ 中的参考实现是可用的here

    算法背后的基本思想(使用 digram 频率爬山以避免不得不多次破译)来自this paper,并且(由第一篇论文的作者)描述为解决单字母替换的已知最快算法密码。

    【讨论】:

      最近更新 更多