我正在考虑crypt kicker问题。我想我可以通过蛮力尝试所有字母排列(也许有一些优化)来解决它。但是,此解决方案的最坏情况复杂性类似于O(permutations of alphabet * number of words)
。
这是对的吗?在最坏的情况下,是否存在复杂度较低的解决方案?
答案 0 :(得分:3)
以下是来自3-dimensional matching的带有k字母字母的Crypt Kicker的NP硬度的正式证明。
对于每个输入三元组( x , y , z ),将单词 xyz 放入字典。为了确定是否存在大小为n的匹配,请求解密n字密文abc def ghi ....显然,这种减少是多时间的。如果存在3-d匹配( x 1 , y 1 , z 1 ),...,( x n , y n , z n ),然后置换 x 1 →a, y 1 →b, z 1 →c, x 2 →d,......目睹了有效的解密。相反,如果存在有效的解密置换π,则我们恢复3-d匹配(π(a),π(b),π(c)),(π(d),π(e),π(f) )),...。
答案 1 :(得分:1)
您可以通过强力解决任何加密问题,问题是解决所需的时间。因此,对于多字母密码,您希望依赖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)。
答案 2 :(得分:1)
我认为总会有一些需要回溯的病态病例。
这是一种技术,起初看起来更容易:在单词中寻找重复字母的模式。如果您知道单词“banana”,那么“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到变量的赋值,使得等式产生为真=>如果你能解决替代问题,你可以解决SAT =>它是NP-Complete。