【发布时间】:2011-12-03 16:24:40
【问题描述】:
我正在考虑crypt kicker 的问题。我想我可以通过蛮力尝试字母的所有排列来解决它(也许有一些优化)。然而,这个解决方案的最坏情况复杂性看起来像O(permutations of alphabet * number of words)。
正确吗?有没有最坏情况下复杂度更低的解决方案?
【问题讨论】:
标签: algorithm complexity-theory
我正在考虑crypt kicker 的问题。我想我可以通过蛮力尝试字母的所有排列来解决它(也许有一些优化)。然而,这个解决方案的最坏情况复杂性看起来像O(permutations of alphabet * number of words)。
正确吗?有没有最坏情况下复杂度更低的解决方案?
【问题讨论】:
标签: algorithm complexity-theory
这是 Crypt Kicker 的 NP 硬度的正式证明,使用 k 字母,从 3-dimensional matching 减少而来。
对于每个输入三元组(x、y、z),将单词xyz放入字典中.要确定是否存在大小为 n 的匹配,请请求解密 n 字密文 abc def ghi ... 。显然,这种减少是多时间的。如果存在 3-d 匹配 (x1, y1, z1), …, (xn, yn, zn),那么排列x1→a, y1 →b, z1→c, x2→d, ... 见证了有效的解密。相反,如果存在一个有效的解密排列 π,那么我们恢复一个 3-d 匹配 (π(a), π(b), π(c)), (π(d), π(e), π(f )), ... .
【讨论】:
您可以通过蛮力解决任何加密问题,问题在于解决所需的时间。因此,对于多字母密码,您需要依赖Kasiski 方法,这本质上是一种分而治之的方法。您需要做的是将密文转换为 X 个单字母密码。根据您问题中的链接,这是重要的部分:
Sample Input 6
and
dick
jane
puff
spot
yertle
bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
如果是这种情况,则最多有 26 个排列。 如果没有看到更多排列,就很难提供任何其他信息。您是否知道任何其他示例输入/输出对?
为了回答您关于复杂性的实际问题,我将使用 approximate big oh 作为参考
所以首先我们看一下加密方法:
function encrypt(Text textToEncrypt, Alphabet substitutionAlphabet)
{
Alphabet textAlphabet = textToEncrypt.getAlphabet(); //O(1) should be a constant look up to get your own property
for(character current : textToEncrypt) //O(N) must touch all elements
{
current = substitutionAlphabet.lookupChange(current, textAlphabet); //O(N) worst case map lookup
}
}
所以看起来加密函数是 O(N) 最坏的情况,我的实现是相当做作的。并且解密应该是相同的,所以也会产生 O(N)。
【讨论】:
我认为总会有一些病态的案例需要回溯。
这是一种乍一看似乎使事情变得更容易的技术:寻找单词中重复字母的模式。如果您知道“香蕉”这个词,那么“xzyzyz”表示 x = b、z = a、y = n。但是这种技术还允许您构建一个字典,以标记具有香蕉状后缀的单词,从而允许您为前缀强制执行特定的可能解决方案。例如,字典条目 ADFbanana、BCFbanana、BDEbanana 与单词 PRSbanana 一起要求用户选择 P = A 或 B、R = C 或 D、S = E 或 F,这样这些映射中的一个恰好是两种可能性中的第一种。
鉴于这些构建块,我认为您可以采用 (A|B|~C) & (D|~E|F) &... 形式的布尔方程并将其编码为替换问题,这样替代问题的解决方案将产生对变量的 T/F 分配,使方程产生 true =>如果您可以解决替代问题,您可以解决 SAT =>它是 NP-Complete。
【讨论】: