题目传送门在此。
这关还是维吉尼亚密码,给了我们三个加密文本,不过没有告诉我们长度,但是频率统计还是奏效。
于是乎,首先在这里分别提交三个加密文本,可以发现最可能的长度是3或者9,3个文本都满足这一特性。
然后用程序统计频率,尝试将最高频的字母当作e来进行解密:
def decode(s, key): ans = '' l = len(key) for k in xrange(len(s)): i = k / l j = k % l ans += chr((ord(s[i * l + j]) - ord(key[j]) + 26) % 26 + ord('a')) return ans def search(base_s, deep, sec, key): if deep == sec: text = decode(base_s, key) if text.find('the') >= 0: print(text[0:20], key) return s = base_s[deep::sec] d = {} for c in s: if c in d: d[c] += 1 else: d[c] = 1 ans = sorted(d.items(), key=lambda d:d[1]) low = ans[len(ans) - 1][1] - 3 for one in ans: if one[1] >= low: search(base_s, deep + 1, sec, key + chr((ord(one[0]) - ord('E') + 26) % 26 + ord('A')))
其中我架设解密文本中一定含有the,以尽量减少人工选择量,然后low可以根据个人感觉来设定,只有出现次数不小于low的才会被考虑当作e。
首先尝试长度为3:
>>> search(s2, 0, 3, '') ('wsaoesamfiwcpedqched', 'KTC') ('wsvoenamaiwxpeyqcced', 'KTH')
很显然不太对,然后尝试长度为9,由于比较长,只选择一部分:
('whentsumeilgotdkcges', 'KEYLECQTD') ('whentsumailgotdkcces', 'KEYLECQTH') ('whentsumlilgotdkcnes', 'KEYLECQTW') ('whentsumrilgotdkctes', 'KEYLECQTQ') ('whentspmeilgotdfcges', 'KEYLECVTD') ('whentspmailgotdfcces', 'KEYLECVTH') ('whentspmlilgotdfcnes', 'KEYLECVTW') ('whentspmrilgotdfctes', 'KEYLECVTQ') ('whenthumeilgotskcges', 'KEYLENQTD') ('whenthumailgotskcces', 'KEYLENQTH') ('whenthumlilgotskcnes', 'KEYLENQTW') ('whenthumrilgotskctes', 'KEYLENQTQ') ('whenthpmeilgotsfcges', 'KEYLENVTD') ('whenthpmailgotsfcces', 'KEYLENVTH') ('whenthpmlilgotsfcnes', 'KEYLENVTW') ('whenthpmrilgotsfctes', 'KEYLENVTQ') ('wxeyjsumeibgzjdkcgei', 'KOYAOCQTD') ('wxeyjsumaibgzjdkccei', 'KOYAOCQTH') ('wxeyjsumlibgzjdkcnei', 'KOYAOCQTW') ('wxeyjsumribgzjdkctei', 'KOYAOCQTQ') ('wxeyjspmeibgzjdfcgei', 'KOYAOCVTD') ('wxeyjspmaibgzjdfccei', 'KOYAOCVTH') ('wxeyjspmlibgzjdfcnei', 'KOYAOCVTW')
其中的whenth部分看起来比较像when the,然后看对应的key,key似乎就应该是keylength。于是解密检查,确认密钥正确。
然后用此密钥,解密即可得到下一关的password。