一、原题

[原题链接]
从前有个很厉害的人物演讲了一堆很厉害的东西,可是我读书少,认识人不多,你知道这个人叫啥不。。

答案格式wctf{名字}

友情提示1、外国人,只要名字就可以了,就别要姓了,首字母大写。

友情提示2、说过我读书少,外国人的名字和姓我是分不清的,反正答案就是大家最常叫的那个。。

以下就是这个人讲话的节选:

EB BMQF KYJRD, IM ICHZZZ YWELXABD, ICCH PVLQ EB PGJS, UEZW PAGE RDS IGJOW QQQNHQO ZU BOTOSNS RD CFU YCFUQA. VGJQP RDWD AKIYWPU HDQ TZXLZSO, AONK CSYHPWHTRL CQ YISCLAWBD FWG ECAB VSIAZQCZ ER CWGH PSDWGICYB PC LRO YDRECYDJ ZZBYHHJ. PVP ENOGHQ CQ WKIYJ WAPUGYOYV SVZ YJGHHPAR WFA NDJH ER OSCYGYS VSNFZXLZ EKC UWRZA.

YRU HSH PFFPNAH VSIAZQQ ID YCOTQ - YRR OD Y QLOJ HZ ZAOC YNAD, PVZXED LUKO HH JSPG; BZW WG D YOWO PC EYPHWH, HSRSCV HKXOEWJAR ZC OCH - MXR O FYHZ WM PPDP HSH XICGCJ ZI W WRLC EZGHWRKR GEUSCUWH, MPDP WY YJR BCWF RSP, “PAXZLAEBR GJ SRNA, SYPWPQR WY RNWMXJWHTRL” - Y GEUSCUWH WULLLOH WFA NRKICY CJSXLCO ZI IOY: PMCDLJM, NKJPURU, GGOSLVC, LQB KLU EHDHJB.

NDL KP DKFRH WULLLOH WFAGP CJSXLCO L ENOYG WBO EHCMDJ OWOGWBNH, BZURD LQB GZXRD, HYOH DLZ HHQP, WFWH FYJ LVQQFP Y AZUC TCXGPTFO HWQH BCC YHZ PYJYTQB? HLJH JRS XZLL WY RDOE FEGERPEQ HDBCCW?

EB WFA WRLC SLQPCCB KT WFA HRPHR, MJZJ Y TPZ CSYHPWHTRLO SDTA MHCJ RUYJHPG PVP PKZP MB OHDABOLLC QUCARZP EB LRO SRSN ZI IOILKQA GYJUPU. W GM BZW OVLQI TCRK HSLQ FPVNKBDLZEZTWW - L SSWFMIS LR. T BK YRR PPOGAJP RDOE YJM RD ID UKIWG ALNKYJUP NHONHQ KTWF OYB KHSHP DPRNHS RP OYB KHSHP UPQCNOELMJ. WFA PQCNUJ, PVP DWWEK, HSH ZSGRRECY UDWNK SS EPEBR RK EKGO PQBAOGRSN HLJH WLEDH RSN NRSJHCB WBO YHZ ZFK DHPRS LR – YJR WFA ROMS QUMI EKYP QLPA NDL HCXJU WLEDH WFA HRPHR.

DLZ DR, AJ DAZWRU OXHPEQLQQ: LVI BZW SVLW UCFU YCFQRNM FYJ OR BCC WKI - WGV UDOE WKI FYJ OR BCC WKIC AKIYWPU.

XB BSWOMS NLRENPQQ CQ RDS ZMNZO: WGV LKH ZFWH DKAFTFY KTOJ RZ DKF BMQ, ESP HKYP EREAHSHP KP AWB GM TZU PVP DNSPGMI ZI IOY.

DEBLOJU, ZFAHSHP MZX WFP AEHTCCJG RD OXHPEQL MN NLRENPQQ CQ RDS ZMNZO, WGV MB FV PVP QWAP FEUS QPOYGYNRD MB DWPABRWF OYG OONUGBWNH SVTFF KP YOY RD MZX. KTWF O JMKR FMJGNLCJQP MQF RLHM VSNS UCSOCG, KTWF VTVRKFJ RDS IGJOW HQRRH KT RSN OHCZG, JAH XQ UZ DKFEK PC OCWR WFA WDLZ HH HCGH, ODNGJU KGO MOCOGTQE OYG DWD FAZA, XIE IJCHLLC EKYP SHPA ZQ AOCWF UZG’O HRPG XXQP EUSHM EC CFU KKY.


二、writeup

1、凯撒密码

分析题目,原文是英文,密文也全都是英文字母,很明显的古典密码。
这里有一个介绍古典密码的链接:[古典密码]
先考虑最简单的[凯撒密码],即简单的对全部字母进行移位,如把全部字母后移两位,那么对于原文:

abcdef

对应的密文将是:

cdefgh

这种简单的加密方式十分容易破解,因为英文中每个字母出现的频率是相对固定的,只要对于足够长的密文,统计其中字母出现的频度,与标准频度表进行比对,就可以轻易地发现原文字母与密文字母的对应关系。
标准频率表如下:

stdFreq = {
'A':8.2 ,'N':6.7,
'B':1.5, 'O':7.5,
'C':2.8, 'P':1.9,
'D':4.3, 'Q':0.1,
'E':12.7, 'R':6.0,
'F':2.2, 'S':6.3,
'G':2.0, 'T':9.1,
'H':6.1, 'U':2.8,
'I':7.0, 'V':1.0,
'J':0.2, 'W':2.4,
'K':0.8 ,'X':0.2,
'L':4.0 ,'Y':2.0,
'M':2.4 ,'Z':0.1
}

做字频统计尝试破解,字母频度分布较为均匀,没有结果,猜测使用了凯撒密码的进阶版,[维吉尼亚密码],即采用某密钥,循环对字母进行移位。

2、维吉尼亚密码

于是进一步采用了经典的维吉尼亚密码的解法,首先通过重复序列的间隔推断出密码长度,进而将密文分组进行频度分析,得出密钥。具体方法百科里有介绍:[维吉尼亚密码]
在这一步的工作中写了大段的代码进行分析,包括下面使用的词频统计的代码都是在这一步中写的,可以说这一步是得到正确答案的基础,可事实上在这一步并没有得出结果,原因是自己走了一个弯路:

在解密之前去掉了密文的所有标点、空格和换行符

因为自己一直沿着经典思路解题,同时做了不必要的处理,导致耽搁了较长时间,后来转过这个弯,决定采用自己的思路进行分析,答案就显而易见了。

3、粗糙解法

对于本题,单词间隔和标点符号都给出的情况下,字频分析已经不是十分必要了,更有效的方法是词频分析。
词频分析要注意的主要是两个方面:

1、在维吉尼亚加密中,由于采用一定长度的密钥循环加密,所以一个单词会被加密为不同的形式,而只有那些出现频率极高的单词才会重复地出现,而英语中出现频率最高的一个词是’the’
2、英文中有比较特殊的一个单词——’a’,它只有短短的一个字母,另外的单字母单词还有’I’,但其出现频率显然没有’a’高

于是在统计中,我们重点查看三字母单词和单字母单词的出现的状况。
词频统计python程序如下:

article = """
EB BMQF KYJRD......
"""
import re
#利用非字母字符拆分单词
pattern = re.compile(r'[^A-Za-z]+')
words = re.split(pattern,article)#统计单词出现的次数
wc = {}
for w in words:wc.setdefault(w,0)wc[w] += 1#根据出现的次数进行排序
sortedWc= sorted(wc.items(), key=lambda e:e[1],reverse=True)
print sortedWc

输出为:

[('WFA', 8), ('PVP', 5), ('CQ', 4), ('RD', 4), ('ZI', 4), ('EB', 4), ('RDS', 4), ('Y', 4), ('WY', 3), ('HSH', 3), ('BCC', 3), ('PC', 3), ('O', 3), ('MB', 3), ('WGV', 3), ('BZW', 3), ('KTWF', 3), ('KP', 3), ('FYJ', 3), ('', 2), ('WLEDH', 2), ('EKYP', 2), ('HLJH', 2), ('RDOE', 2), ('L', 2), ('GM', 2), ('MZX', 2), ('IGJOW', 2), ('CJSXLCO', 2), ('OR', 2), ('OYG', 2), ('HH', 2), ('KHSHP', 2), ('LQB', 2), ('W', 2), ('WULLLOH', 2), ('LRO', 2), ('YHZ', 2), ('DLZ', 2), ('ER', 2), ('WKI', 2), ('NDL', 2), ('AKIYWPU', 2), ('GEUSCUWH', 2), ('YRR', 2), ('WRLC', 2), ('ZMNZO', 2), ('YJR', 2), ('KT', 2), ('HRPHR', 2), ('NLRENPQQ', 2), ('WBO', 2), ('IOY', 2), ('OYB', 2), ('LR', 2), ('ID', 2), ('RSN', 2), ('CFU', 2), ('WG', 1), ('UZG', 1), ('IJCHLLC', 1), ('RUYJHPG', 1), ('WM', 1), ('FWG', 1), ('BK', 1), ('ZFK', 1), ('SS', 1), ('YRU', 1), ('QLOJ', 1), ('MJZJ', 1), ('YOWO', 1), ('YISCLAWBD', 1), ('RP', 1), ('YDRECYDJ', 1), ('AONK', 1), ('HRPG', 1), ('SDTA', 1), ('DWD', 1), ('KYJRD', 1), ('WDLZ', 1), ('HKYP', 1), ('SRSN', 1), ('TPZ', 1), ('ENOYG', 1), ('DPRNHS', 1), ('RDWD', 1), ('WAPUGYOYV', 1), ('D', 1), ('LVQQFP', 1), ('DNSPGMI', 1), ('ZZBYHHJ', 1), ('HCGH', 1), ('BMQF', 1), ('QWAP', 1), ('SVZ', 1), ('T', 1), ('JAH', 1), ('GJ', 1), ('UEZW', 1), ('DKF', 1), ('PQBAOGRSN', 1), ('YJGHHPAR', 1), ('GZXRD', 1), ('YNAD', 1), ('OD', 1), ('QUMI', 1), ('CSYHPWHTRLO', 1), ('YCFQRNM', 1), ('OVLQI', 1), ('HZ', 1), ('OCH', 1), ('WFWH', 1), ('HDQ', 1), ('HSRSCV', 1), ('LKH', 1), ('DKFRH', 1), ('YJM', 1), ('XICGCJ', 1), ('ICCH', 1), ('PKZP', 1), ('ESP', 1), ('PGJS', 1), ('CWGH', 1), ('OXHPEQLQQ', 1), ('AZUC', 1), ('MOCOGTQE', 1), ('GGOSLVC', 1), ('UCFU', 1), ('FMJGNLCJQP', 1), ('VSIAZQCZ', 1), ('BMQ', 1), ('UCSOCG', 1), ('MPDP', 1), ('MQF', 1), ('UKIWG', 1), ('RZ', 1), ('PAXZLAEBR', 1), ('JMKR', 1), ('VTVRKFJ', 1), ('AJ', 1), ('EREAHSHP', 1), ('ALNKYJUP', 1), ('EPEBR', 1), ('XXQP', 1), ('ZC', 1), ('PQCNUJ', 1), ('IOILKQA', 1), ('EC', 1), ('PMCDLJM', 1), ('ZU', 1), ('XIE', 1), ('ZQ', 1), ('WKIYJ', 1), ('HCXJU', 1), ('KKY', 1), ('DKAFTFY', 1), ('ECAB', 1), ('YCOTQ', 1), ('MXR', 1), ('PVZXED', 1), ('NRSJHCB', 1), ('OONUGBWNH', 1), ('HWQH', 1), ('YWELXABD', 1), ('LUKO', 1), ('PYJYTQB', 1), ('FV', 1), ('WFAGP', 1), ('ZSGRRECY', 1), ('BCWF', 1), ('EKC', 1), ('SYPWPQR', 1), ('NHONHQ', 1), ('WKIC', 1), ('QQQNHQO', 1), ('NKJPURU', 1), ('TZU', 1), ('FPVNKBDLZEZTWW', 1), ('ROMS', 1), ('JSPG', 1), ('TZXLZSO', 1), ('PSDWGICYB', 1), ('BZURD', 1), ('ENOGHQ', 1), ('EHCMDJ', 1), ('GYJUPU', 1), ('UDWNK', 1), ('AEHTCCJG', 1), ('KTOJ', 1), ('QLPA', 1), ('XB', 1), ('UPQCNOELMJ', 1), ('SHPA', 1), ('AWB', 1), ('VGJQP', 1), ('SVLW', 1), ('HDBCCW', 1), ('OHCZG', 1), ('XQ', 1), ('VSNFZXLZ', 1), ('VSNS', 1), ('UDOE', 1), ('FYHZ', 1), ('XZLL', 1), ('UWRZA', 1), ('DWPABRWF', 1), ('UZ', 1), ('CSYHPWHTRL', 1), ('PVLQ', 1), ('HYOH', 1), ('HKXOEWJAR', 1), ('JRS', 1), ('EHDHJB', 1), ('NRKICY', 1), ('DKFEK', 1), ('RK', 1), ('PAGE', 1), ('QPOYGYNRD', 1), ('TCRK', 1), ('MN', 1), ('DHPRS', 1), ('OWOGWBNH', 1), ('SLQPCCB', 1), ('FEGERPEQ', 1), ('NDJH', 1), ('HSLQ', 1), ('HQRRH', 1), ('OXHPEQL', 1), ('OCWR', 1), ('DR', 1), ('WFP', 1), ('DAZWRU', 1), ('ZFWH', 1), ('MHCJ', 1), ('BSWOMS', 1), ('BOTOSNS', 1), ('VSIAZQQ', 1), ('YCFUQA', 1), ('DEBLOJU', 1), ('EUSHM', 1), ('HHQP', 1), ('PPDP', 1), ('RNWMXJWHTRL', 1), ('TCXGPTFO', 1), ('PFFPNAH', 1), ('ZFAHSHP', 1), ('SSWFMIS', 1), ('EYPHWH', 1), ('DWWEK', 1), ('EZGHWRKR', 1), ('KLU', 1), ('PPOGAJP', 1), ('IM', 1), ('YOY', 1), ('LVI', 1), ('ICHZZZ', 1), ('ZAOC', 1), ('RLHM', 1), ('AOCWF', 1), ('OHDABOLLC', 1), ('SRNA', 1), ('OSCYGYS', 1), ('FEUS', 1), ('FAZA', 1), ('SVTFF', 1), ('QUCARZP', 1), ('RSP', 1), ('EKGO', 1), ('KGO', 1), ('ODNGJU', 1)]

我们主要关注两个词thea,一个为三字母,一个为单字母,将其中三字母词和单字母词的统计情况打印出来:

print [i for i in sortedWc if len(i[0])==3]
print [i for i in sortedWc if len(i[0])==1]

输出:

[('WFA', 8), ('PVP', 5), ('RDS', 4), ('HSH', 3), ('BCC', 3), ('WGV', 3), ('BZW', 3), ('FYJ', 3), ('MZX', 2), ('OYG', 2), ('LQB', 2), ('LRO', 2), ('YHZ', 2), ('DLZ', 2), ('WKI', 2), ('NDL', 2), ('YRR', 2), ('YJR', 2), ('WBO', 2), ('IOY', 2), ('OYB', 2), ('RSN', 2), ('CFU', 2), ('UZG', 1), ('FWG', 1), ('ZFK', 1), ('YRU', 1), ('DWD', 1), ('TPZ', 1), ('SVZ', 1), ('JAH', 1), ('DKF', 1), ('OCH', 1), ('HDQ', 1), ('LKH', 1), ('YJM', 1), ('ESP', 1), ('BMQ', 1), ('MQF', 1), ('XIE', 1), ('KKY', 1), ('MXR', 1), ('EKC', 1), ('TZU', 1), ('AWB', 1), ('JRS', 1), ('WFP', 1), ('KLU', 1), ('YOY', 1), ('LVI', 1), ('RSP', 1), ('KGO', 1)]
[('Y', 4), ('O', 3), ('L', 2), ('W', 2), ('D', 1), ('T', 1)]

假设排名靠前的'wfa''pvp''rds'都是'the'的密文,计算其偏移,分别为:

wfa: [3, 24, 22]
pvp: [22, 14, 11]
rds: [24, 22, 14]

perfect,重合的地方相当多。
假设成立的话,即这几个词都是the的密文的话,那么密钥中包含这5个偏移:

offsets = [3, 11, 14, 22, 24]

不妨再大胆假设,'hsh'也是'the'的密文,计算其偏移:

[14, 11, 3]

这尼玛……完美,这三个偏移都在假设密钥存在的偏移offsets的范围内,两个假设相互印证。
再观察单字母的情况:

[('Y', 4), ('O', 3), ('L', 2), ('W', 2), ('D', 1), ('T', 1)]

上面是单字母单词和其出现的次数,假设其都是'a''i'的密文,计算其偏移
相对于'a'

[24, 14, 11, 22, 3, 19]

除了19,全部位于offsets内,结果非常好。
考虑最后一个词't'相对于'a'的偏移19不在offsets内,那么估计它就是i的密文了,计算其偏移:

11

棒,11刚好在offsets之内。
那么到这里我们假设,密钥为5位,分别为:

offsets = [3, 11, 14, 22, 24]

将这几个数字表示成对应的字母:

dlowy

稍微变换下顺序:

offsets = [22, 24, 3, 11, 14]

这就成了:

woldy

出题人的名字。。。答案还用说吗。。。?
用这个密钥解密已经可以得出原文。
以上的步骤是在我用后文所述的方法得出答案之后再回头看才得出的,但其中每一步的推测都不够严谨,对原始数据要求较高。
事实上以上步骤能得到结果纯粹因为题目所给的这段话中'the'出现的频率过于高了,按数学建模模的思路就是模型对于'the'出现的频率过于敏感,一旦原始数据中'the'出现的频率较低,则模型将不能得出结果。
对密钥的假设也不够严谨,实际上密钥是有可能多于5位的,而且offsets中的5个数字也不一定都在密钥中。
更通用的做法如下所述。

4、通用解法

为了保证能够得到结果,首先需要的是在假设集offsets中包含尽可能多的数字,即保证offsets中能够涵盖实际的密钥。
在这里我们与前面一样假设假设排名靠前的'wfa''pvp''rds'都是'the'的密文,计算其偏移,分别为:

wfa: [3, 24, 22]
pvp: [22, 14, 11]
rds: [24, 22, 14]

同时,对于所给密文中出现过的单字母单词'Y','O','L','W','D','T',其可能为'a''i',分别计算偏移:

对于'a':
[24, 14, 11, 22, 3, 19]
对于'i':
[16, 6, 3, 14, 21, 11]

取以上各结果取并集,则假设集

offsets = [3, 6, 11, 14, 16, 19, 21, 22, 24]

包含9种偏移。
根据假设,字母偏移的位数只可能在offsets之内,即只能是[3, 6, 11, 14, 16, 19, 21, 22, 24]其中之一。对于每个词,以'wfa'为例,每个字母对应的原文都有9种情况,对应offsets内不同的偏移值,如'w',可能是原文字母往后偏移3位或者6位或者11位或者……,共有9种可能;'f''a'同样有9种可能,则'wfa'对应的原文单词有 9×9×99\times9\times9 种不同的可能,将这些组合与其对应的密钥序列例举出来,观察哪些是完整的单词,哪些是乱码,即可对密钥序列做进一步的分析。而判断某种字母组合是否是一个单词,则可由程序通过在字典文件里的查找做到。
下面这段程序可判断四字母密文可能对应的原文:
先定义全局变量:

#构造好一个字典num和一个列表let完成字符和数字的转换关系
#其中num = {'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, 'h': 7, 'k': 10, 'j': 9, 'm': 12, 'l': 11, 'o': 14, 'n': 13, 'q': 16, 'p': 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'w': 22, 'v': 21, 'y': 24, 'x': 23, 'z': 25}
#let = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
#使用let[n]即可得到位置n处的字母,如let[0]得到'a',let[25]或者let[-1]得到'z'
#使用num[letter]即可得到字母的位置,如num['a']得到0,num['z']得到25
num = {}
j = 0
for i in range(97,97+26):num[chr(i)] = jj += 1let = []
for i in range(26):let.append(chr(ord('a')+i))#打开事先准备好的英文常用3000词字典文件words.txt
#此文件中每行保存一个单词,共3000行
with open('words.txt') as f:s = f.read()#以换行符为标志分割出单词,保存在一个集合(set)中#将单词保存在集合中可以以o(1)的时间复杂度实现查找操作words = set(s.split('\n'))#假设偏移集
offsets = [3, 6, 11, 14, 16, 19, 21, 22, 24]

具体的穷举寻找原单词的函数:

import itertools
def searchRealWord(secretWord):global offsets,num,letlength = len(secretWord)possibleLetters = []realWord = []for i in range(length):possibleLetters.append([])for i in offsets:for j in range(length):possibleLetters[j].append( (let[num[secretWord[j]]-i] ,i) )possibleWords = itertools.product(*possibleLetters)for item in possibleWords:word = ''.join([ i[0] for i in item ])if word in words:realWord.append((word, [i[1] for i in item]))return realWord

上面的函数,接受一个任意长的密文单词,通过穷举查字典,列出其所有可能的原文单词。
这段程序用了各种python黑科技,而换用其他语言不知道要写多少行,在这里不得不感叹python真的太厉害了。但是这段程序的可读性还是有问题,好在功能实现良好,懒得写注释了。
利用前一步得到的结果,所有六字母单词和出现次数如下:

data = [('DPRNHS', 1), ('LVQQFP', 1), ('HSRSCV', 1),
('XICGCJ', 1), ('UCSOCG', 1), ('PQCNUJ', 1),
('PVZXED', 1), ('NHONHQ', 1), ('ENOGHQ', 1),
('EHDHJB', 1), ('NRKICY', 1), ('DAZWRU', 1),
('ICHZZZ', 1), ('ODNGJU', 1)]

依次解密:

for i in data:print searchRealWord(i[0].lower())

输出:

[('people', **[14, 11, 3, 24, 22, 14]**), ('future', [24, 21, 24, 19, 16, 14])]
[('assure', [11, 3, 24, 22, 14, 11]), ('assume', [11, 3, 24, 22, 19, 11])]
[('though', **[14, 11, 3, 24, 22, 14]**)]
[('burden', **[22, 14, 11, 3, 24, 22]**), ('burned', [22, 14, 11, 19, 24, 6]), ('buried', [22, 14, 11, 24, 24, 6])]
[('remark', [3, 24, 6, 14, 11, 22]), ('reward', **[3, 24, 22, 14, 11, 3]**)]
[('marked', [3, 16, 11, 3, 16, 6]), ('market', [3, 16, 11, 3, 16, 16]), ('energy', **[11, 3, 24, 22, 14, 11]**)]
[('though', **[22, 14, 11, 3, 24, 22]**)]
[('season', [21, 3, 14, 21, 19, 3]), ('reason', [22, 3, 14, 21, 19, 3]), ('return', [22, 3, 21, 19, 16, 3]), ('prison', [24, 16, 6, 21, 19, 3])]
[]
[]
[('danger', **[3, 24, 22, 14, 11, 3]**)]
[('effort', **[3, 24, 22, 14, 11, 3]**)]
[('beheld', [3, 3, 22, 3, 24, 24]), ('behold', [3, 3, 22, 19, 24, 24]), ('lonely', [19, 19, 16, 3, 24, 3]), ('itself', **[22, 14, 11, 3, 24, 22]**), ('gently', [24, 3, 16, 14, 24, 3])]
[('common', **[11, 3, 24, 22, 14, 11]**), ('closed', [11, 6, 22, 16, 24, 21])]
[('active', [3, 24, 6, 14, 22, 16]), ('settle', [11, 22, 6, 3, 6, 16]), ('fellow', **[24, 22, 14, 11, 3, 24]**), ('feeble', [24, 22, 21, 21, 6, 16])]
[('yellow', [3, 14, 11, 3, 24, 22]), ('fellow', **[22, 14, 11, 3, 24, 22]**)]
[('source', [6, 14, 11, 3, 14, 22]), ('course', **[22, 14, 11, 3, 24, 22]**), ('church', [22, 21, 11, 3, 14, 19])]
[('battle', **[3, 24, 22, 14, 11, 3]**), ('little', [19, 16, 22, 14, 11, 3])]
[('forgot', [3, 14, 16, 19, 11, 6]), ('forget', [3, 14, 16, 19, 21, 6]), ('follow', [3, 14, 22, 14, 11, 3]), ('feeble', [3, 24, 3, 24, 14, 21]), ('fellow', **[3, 24, 22, 14, 11, 3]**), ('showed', [16, 21, 19, 3, 21, 22]), ('settle', [16, 24, 14, 6, 14, 21]), ('needed', [21, 24, 3, 22, 21, 22])]
[('inside', [6, 16, 21, 24, 6, 16]), ('asking', **[14, 11, 3, 24, 22, 14]**), ('taking', [21, 3, 3, 24, 22, 14]), ('sprang', [22, 14, 22, 6, 22, 14]), ('spring', [22, 14, 22, 24, 22, 14])]

注意手动添加的**之间的部分,答案显而易见了。
更精密的办法是对所有长度的单词进行类似的统计,找出重复最多的序列,这里用不到了。
密钥是:

11, 3, 24, 22, 14

offsets的值改为上述序列

offsets = [11, 3, 24, 22, 14]

首尾循环,初始点待定。
对第一句话EB BMQF KYJRD的单词依次进行解码,输出为:

[('by', [3, 3]), ('if', [22, 22]), ('in', [22, 14])]
[('your', [3, 24, 22, 14]), ('four', [22, 24, 22, 14])]
[('wants', [14, 24, 22, 24, 11])]
[('my', [22, 14])]
[('fellow', [3, 24, 22, 14, 11, 3]), ('follow', [3, 14, 22, 14, 11, 3])]
[]

前两个符合要求的输出是in your,偏移值分别为22,143,24,22,14对照11, 3, 24, 22, 14,猜测遇到空格标点等,密钥一样会往前跳。继续分析其他句子,猜测得到证明。
于是有,密钥从22开始,以[22, 14, 11, 3, 24]的顺序循环,遇标点或空格则密钥继续往前跳。
解密

article = """EB BMQF KYJRD, IM ICHZZZ YWELXABD, ICCH PVLQ EB PGJS, UEZW PAGE RDS IGJOW QQQNHQO ZU BOTOSNS RD CFU YCFUQA. VGJQP RDWD AKIYWPU HDQ TZXLZSO, AONK CSYHPWHTRL CQ YISCLAWBD FWG ECAB VSIAZQCZ ER CWGH PSDWGICYB PC LRO YDRECYDJ ZZBYHHJ. PVP ENOGHQ CQ WKIYJ WAPUGYOYV SVZ YJGHHPAR WFA NDJH ER OSCYGYS VSNFZXLZ EKC UWRZA.YRU HSH PFFPNAH VSIAZQQ ID YCOTQ - YRR OD Y QLOJ HZ ZAOC YNAD, PVZXED LUKO HH JSPG; BZW WG D YOWO PC EYPHWH, HSRSCV HKXOEWJAR ZC OCH - MXR O FYHZ WM PPDP HSH XICGCJ ZI W WRLC EZGHWRKR GEUSCUWH, MPDP WY YJR BCWF RSP, "PAXZLAEBR GJ SRNA, SYPWPQR WY RNWMXJWHTRL" - Y GEUSCUWH WULLLOH WFA NRKICY CJSXLCO ZI IOY: PMCDLJM, NKJPURU, GGOSLVC, LQB KLU EHDHJB.NDL KP DKFRH WULLLOH WFAGP CJSXLCO L ENOYG WBO EHCMDJ OWOGWBNH, BZURD LQB GZXRD, HYOH DLZ HHQP, WFWH FYJ LVQQFP Y AZUC TCXGPTFO HWQH BCC YHZ PYJYTQB? HLJH JRS XZLL WY RDOE FEGERPEQ HDBCCW?EB WFA WRLC SLQPCCB KT WFA HRPHR, MJZJ Y TPZ CSYHPWHTRLO SDTA MHCJ RUYJHPG PVP PKZP MB OHDABOLLC QUCARZP EB LRO SRSN ZI IOILKQA GYJUPU. W GM BZW OVLQI TCRK HSLQ FPVNKBDLZEZTWW - L SSWFMIS LR. T BK YRR PPOGAJP RDOE YJM RD ID UKIWG ALNKYJUP NHONHQ KTWF OYB KHSHP DPRNHS RP OYB KHSHP UPQCNOELMJ. WFA PQCNUJ, PVP DWWEK, HSH ZSGRRECY UDWNK SS EPEBR RK EKGO PQBAOGRSN HLJH WLEDH RSN NRSJHCB WBO YHZ ZFK DHPRS LR -- YJR WFA ROMS QUMI EKYP QLPA NDL HCXJU WLEDH WFA HRPHR.DLZ DR, AJ DAZWRU OXHPEQLQQ: LVI BZW SVLW UCFU YCFQRNM FYJ OR BCC WKI - WGV UDOE WKI FYJ OR BCC WKIC AKIYWPU.XB BSWOMS NLRENPQQ CQ RDS ZMNZO: WGV LKH ZFWH DKAFTFY KTOJ RZ DKF BMQ, ESP HKYP EREAHSHP KP AWB GM TZU PVP DNSPGMI ZI IOY.DEBLOJU, ZFAHSHP MZX WFP AEHTCCJG RD OXHPEQL MN NLRENPQQ CQ RDS ZMNZO, WGV MB FV PVP QWAP FEUS QPOYGYNRD MB DWPABRWF OYG OONUGBWNH SVTFF KP YOY RD MZX. KTWF O JMKR FMJGNLCJQP MQF RLHM VSNS UCSOCG, KTWF VTVRKFJ RDS IGJOW HQRRH KT RSN OHCZG, JAH XQ UZ DKFEK PC OCWR WFA WDLZ HH HCGH, ODNGJU KGO MOCOGTQE OYG DWD FAZA, XIE IJCHLLC EKYP SHPA ZQ AOCWF UZG'O HRPG XXQP EUSHM EC CFU KKY.
"""
article = article.lower()i = 0
result = []
while i<len(article):for j in range(5):if i+j>len(article):breakif article[i+j].isalpha():result.append(let[num.get(article[i+j],' ')-[22,14,11,3,24][j]])else:result.append(article[i+j])i += 5
print ''.join(result)

注意每段开头要有四个空格,每段结束没有空格,这些格式是手动加的,上面的代码中就是这种格式。
输出:

in your hands, my fellow citizens, more than in mine, will rest the final success or failure of our course. since this country was founded, each generation of americans has been summoned to give testimony to its national loyalty. the graves of young americans who answered the call to service surround the globe.now the trumpet summons us again - not as a call to bear arms, though arms we need; not as a call to battle, though embattled we are - but a call to bear the burden of a long twilight struggle, year in and year out, "rejoicing in hope, patient in tribulation" - a struggle against the common enemies of man: tyranny, poverty, disease, and war itself.can we forge against these enemies a grand and global alliance, north and south, east and west, that can assure a more fruitful life for all mankind? will you join in that historic effort?in the long history of the world, only a few generations have been granted the role of defending freedom in its hour of maximum danger. i do not shank from this responsibility - i welcome it. i do not believe that any of us would exchange places with any other people or any other generation. the energy, the faith, the devotion which we bring to this endeavour will light our country and all who serve it -- and the glow from that fire can truly light the world.and so, my fellow americans: ask not what your country can do for you - ask what you can do for your country.my fellow citizens of the world: ask not what america will do for you, but what together we can do for the freedom of man.finally, whether you are citizens of america or citizens of the world, ask of us the same high standards of strength and sacrifice which we ask of you. with a good conscience our only sure reward, with history the final judge of our deeds, let us go forth to lead the land we love, asking his blessing and his help, but knowing that here on earth god's work must truly be our own.

搜之,这是美国总统John F. Kennedy的就职演说


三、flag

wctf{Kennedy}


四、总结

密码破解,极有意思。

IDF实验室-伟人的名字相关推荐

  1. idf实验室--简单编程字符统计

    idf实验室--简单编程字符统计,有需要的朋友可以参考下. 第一眼看这道题很简单,不就是字符统计么,可是题目要求2s内回答,而且每次打开的页面需要统计的字符串内容都会变,这就蛋疼了,于是乎上网学习下如 ...

  2. 百密一疏——伟人的名字

    题目描述 从前有个很厉害的人物演讲了一堆很厉害的东西,可是我读书少,认识人不多,你知道这个人叫啥不.. 答案格式wctf{名字} 友情提示1.外国人,只要名字就可以了,就别要姓了,首字母大写. 友情提 ...

  3. IDF实验室·牛刀小试1-5

    1.被改错的密码 从前有一个熊孩子入侵了一个网站的数据库,找到了管理员密码,手一抖在数据库中修改了一下,现在的密码变成了 cca9cc444e64c8116a30la00559c042b4,那个熊孩子 ...

  4. IDF实验室-图片里的英语

    原题: 一恒河沙中有三千世界,一张图里也可以有很多东西. 不多说了,答案是这个图片包含的那句英文的所有单词的首字母. 首字母中的首字母要大写,答案格式是wctf{一坨首字母} 加油吧少年!看好你哦~  ...

  5. IDF 实验室 初探乾坤

    简单编程-字符统计 还可以模拟网页访问,有空试一下. ----------------------------------- 速度要快,用AutoHotKey,语法不太适应 ^d:: StringCa ...

  6. IDF实验室-抓到一只苍蝇

    感觉这道题对我已经有难度了 一.原题 报告首长!发现一只苍蝇.. 在哪? here! 卧槽?!好大一坨苍蝇.. 文件地址: http://pan.baidu.com/s/1bnGWbqJ 提取码:oe ...

  7. IDF实验室 聪明的小羊

    聪明的小羊 2015-01-06 19:21:43 作者:admin 1684 62  一只小羊跳过了栅栏,两只小样跳过了栅栏,一坨小羊跳过了栅栏... tn c0afsiwal kes,hwit1r ...

  8. idf实验室聪明的小羊

    一只小羊跳过了栅栏,两只小样跳过了栅栏,一坨小羊跳过了栅栏... tn c0afsiwal kes,hwit1r  g,npt  ttessfu}ua u  hmqik e {m,  n huiouo ...

  9. IDF实验室之牛刀小试-天孤剑-的微博

    在首页下面 寒 近 嗜 好 酒   剑 动 秀 清 风 的剑里面就可以找到,微博名@无所不能的魂大人 提交,通过!

最新文章

  1. confluence6.15.4部署及问题汇总
  2. NYOJ 618 追击
  3. bzoj 3195 奇怪的道路
  4. MySQL 高级 loop循环
  5. (八)React原理
  6. 基于webpack搭建的vue element-ui框架
  7. 汇编语言---统计数据区的正、负数并分开存放
  8. std c++ 获取运行时间封装
  9. 使用Java实现面向对象编程(1)
  10. 请不要再蹭我了,谢谢
  11. inotify监控文件变化
  12. 怎么新建web程序_前端程序员发展潜力最好,那该怎么学好web前端开发?
  13. Python+大数据技术框架和数仓基础(一)
  14. 电脑重启只剩下c盘怎么办_我的电脑正在正常运行突然自动重启了,重启后发现系统只剩下C盘了,请教怎么恢复?...
  15. 博取仪器3D产品配置
  16. 如何打造以人为本的移动游戏
  17. php weixin provider,14、ABPZero系列教程之拼多多卖家工具 新建微信公众号模块
  18. __call__ 的用法
  19. 数据分析方法:非正态数据转化成正态数据
  20. 树莓派4B openwrt wifi 提升速度

热门文章

  1. 疯狂Spring Cloud微服务架构实战
  2. 开心消消乐java下载_开心消消乐原版下载安装
  3. DeepCTR:易用可扩展的深度学习点击率预测算法库
  4. 书评:薛定谔猫与生物学鸽子:《生命是什么?》出版75周年记
  5. SCCM2012软件分发
  6. Java的socket简单语法实例以及多线程
  7. 知道创宇区块链安全实验室|UmbNetwork 攻击事件分析
  8. 学会享受寂寞,才能享受爱情
  9. 阿里云API网关调用示例
  10. 从0到1搭建电商营销数据分析平台(一)