一位同事最近在尝试找到(不同的)研究工作时被问到这个问题:
给出10个128个字符的字符串,它们以完全相同的方式排列,解码字符串。原始字符串是英文文本,其中删除了空格,数字,标点符号和其他非字母字符。
在给出答案之前,他有几天时间考虑过这个问题。你会怎么做?您可以使用任何计算机资源,包括字符/单词级语言模型。
答案 0 :(得分:5)
这是一个基本的transposition cipher。我上面的问题只是确定它是换位密码还是替换密码。这种系统的密码分析相当简单。其他人已经提到过基本方法。最佳方法将尝试首先放置最难和最稀有的字母,因为这些字母将倾向于唯一地识别它们周围的字母,这极大地减少了后续的搜索空间。简单地找到 放置“a”(没有双关语)的地方并不难,但找到“q”,“z”或“x”的位置是更多的工作。
算法质量的首要目标不是解密文本,因为它可以通过比蛮力方法更好地完成,也不仅仅是为了快速,但它应该消除的可能性,如同可能
由于您可以同时使用多个字符串,因此尝试从最稀有字符创建单词将允许您并行测试字典攻击。尽可能快地找到每个字符串中rarest术语的正确位置将同时解密该密文加上所有其他字符。
如果你搜索转置密码的密码分析,你会发现一堆遗传算法。这些旨在提高在GA工作的人的研究信誉,因为这些在实践中并不是最佳的。相反,您应该查看一些基本的优化方法,例如分支和绑定,A *以及各种统计方法。 (你应该走多远取决于你在算法和统计方面的专业水平。:)我会多次在确定性方法和统计优化方法之间切换。)
在任何情况下,计算应该肮脏廉价且速度快,因为初始猜测的规模可能非常大。最好有一种廉价的方法来首先过滤掉很多可能的位置,然后花更多的CPU时间来筛选更好的候选人。为此,有一种方法可以描述每个阶段的处理阶段和计算工作量。 (至少这是我所期望的,如果我把这作为面试问题。)
你甚至可以buy a fairly credible reference book解密双转置密码。
更新1:查看these slides,了解有关迭代改进的更多建议。它不是一个很好的幻灯片参考集,但它很容易访问。更重要的是,虽然幻灯片是关于GA和模拟退火(在转换密码密码分析的搜索结果中出现的方法),但作者提倡在使用A *或其他方法时反对这些方法。 :)
答案 1 :(得分:1)
首先,您需要测试正确的排序。一种相当简单的东西,比如能够使用按使用频率排序的字典将大多数文本分解为单词而无需回溯。
你有一个,你可以玩各种方法。我会尝试两个:
使用遗传算法,基于2和3个字母的元组进行评分(您可以从某个地方获取或自己生成)。遗传算法的难点在于找到可以分段和重构的过程的良好描述。我猜想像“将片段x移动到片段y之后”这样的东西将是一个很好的方法,其中索引是原始文本中的位置(因此读取“dna”时更改)。此外,您可能需要扩展评分,使您更接近结尾的“真实”文本 - 例如验证算法运行的长度,或完整的单词。
使用图表方法。你需要通过字母位置图找到一致的路径,也许是使用从对频率中获得的权重进行波束宽度搜索。但是我不确定你是如何处理字符串的结尾并重新启动的。也许10个句子足以识别出很好的概率好的起始候选人(来自字母频率) - 不会让我感到惊讶。
这是一个很好的问题:o)我怀疑10个句子是一个强约束(对于每一步你很有可能在几个字符串中有共同的字母对 - 你可能想要通过丢弃最不可能的概率来组合概率,除非你包括单词开始/结束对)所以我认为图表方法将是最有效的。
答案 2 :(得分:0)
首先,您需要一个随着正确排列增加的可能性而增加的评分函数。一种方法是预先计算标准英语中三元组的频率(从Gutenburg项目中获取一些数据)并将所有三个字符串中所有三元组的频率相加。你可能会发现四胞胎比三胞胎更好。
其次,您需要一种方法来产生排列。一种称为爬山的方法采用十个弦并进入一个循环。从1到128中选择两个随机整数,并交换所有十个字符串中的相关字母。计算新排列的分数并将其与旧排列进行比较。如果新的排列是一个改进,保持它并循环,否则保持旧的排列和循环。当改进的数量减慢到某个预定阈值以下时停止。向用户呈现结果,用户可以接受它,接受它并手动进行更改,或拒绝它,在这种情况下,您可以从随机数生成器中不同点的原始字符串集重新开始。
您可以尝试模拟退火,而不是爬山。我会将您推荐给Google了解详细信息,但我们的想法是,不要总是保持两种排列的优势,有时候你会保留两种排列中较小的一种,希望它能带来更好的整体结果。这样做是为了消除爬坡在搜索空间中陷入局部最大值的趋势。
顺便说一下,它是“置换”而不是“置换”。
答案 3 :(得分:0)
Frequency analysis会彻底修剪搜索空间。英文散文中最常见的字母是well-known。
计算加密输入中的字母,并按最常见的顺序排列。匹配最多计数到最多计数,将密码文本转换回尝试的纯文本。它将接近正确,但可能不完全正确。手动,迭代地调整您的排列,直到出现纯文本(通常需要很少的迭代。)
如果您发现手工检查可憎,请通过拼写检查程序运行原始文本,并尽量减少违规计数。