xor_game
ciMbOQxffx0GHQtSBB0QSQIORihXVQAUOUkHNgQLVAQcAVMAAAMCASFEGQYcVS8BNh8BGAoHFlMAABwCTSVQC2UdMQx5FkkGEQQAAVMAAQtHRCNLF0NSORscMkkaHABSExIYBQseUmBCFgtSKwEWfwELFRcGbzwEDABHVS8DDAcXfwUcMQwCDUUBCgYYSQEBATNKGwQeOkkbPhsYERYGDB0TYzwCUSVCDE8dKh0BNg4GAAkLSVMWHBpHQCxQF08AOhkWPh1OAA0XRQQRBQJKQyVKFghSMA95Gh8LGhEHBB8YEE4UViFaEQEVfwAdfx0GEUUWAAARGxpHTiFQERx4FkkROgUHERMXRTpUCANtYy9RFk8TLEkHNwxOFhcbAhsASR0STC1GCk8UMwYEOhsdfiEdRR0bHU4QSDRLHR0XO0kGMQ0LEgATERYQSQgORDJaWAsXMgYdfxsbGAB4LRYVGxpHUyFXHU8TMQ1TPRsLFREaDB0TSRoIASJGGR1SKwEWfwUBFQFSChVUHQYCASNWFQ0XLRocMgxkNgoAABd+PRkIKwkDEAoTLQ1TKwELVAgHFhoXRU4BUy9OWBsaOkkeMAYAVAQcAVMXCBwEQDNQci4HJwAfNggcDUUXHQcGDAMCASFGCxsaOh0aPAAdGUUQBBoASRoIASNCCBsHLQxTMgAdABx4IxoYBQcJRmBXEApSNgcHOgcdEUUeDBURRU4FVDQDGQMBMEkVNgUCHQsVRQccDE4XVDJGcjsaOhsWfwgcEUUTCQQVEB1HTCVOFx0bOhpTKwEcGxAVDRwBHU4TSSUDHQ4AKwF5FkkMEQkbAAURSSdHQC0pPAYXO0kSLEkaHABSFAYdDBpHQyVCDRsLfwYVfwgbABAfC1MYDA8RRDMpKwcXMQ5TNhpOGgoGRRAcCAEUDWBQFQAZOkkUOhoaARcXbzYCDABHVilPDE8TMxocfxsLAAQbCxYQSQwITyUDCB0dKg0fJkk/HQsVRTURBwlHTDVQGwMXVSYQPBwCAG8mDQERDGQuAShGGR1SMwYFOkVOPUUQAB8dDBgCASlNWAMdKQx5EwYYEUUbFlMVSR4ITiwDFwlSLB0BKg4JGAwcAlMWBRsCDCdRHQocfwgfOAgLfiQBRRcRGgELQDRGWAIbPBsccgsbBhYGRRwSSRkOTyQpOgMXOg0aMQ5OAA0ACgYTAU4KWGBVHQYcLGMqOggcB0UBERIAAAEJRCQDEQFSKwEWfwsLGAwXA3kyBhsVKwkDGgoeNgwFOkkaHAQGRRIYBU4EQC4DEAoTLWM2KQwAVAQcERoXAB4GVSUDHAYBPBsWKwxCVCxSCBYASRoPRGBMDAcXLUkHNwwHBkUdEh1+OgEKRGBAGQFSMQYHfw4cFRYCRQccDE4KTi1GFht4EwwVK0kaG0UGDRZULA8UVWBXF08VMEkkOhoaWEUGDRZUDQsGRWBODRwGfwccK0kcEREHFx1UHQFHTy9UEAoAOmMgOgxCVCxSEhYVG049QC4DPgMdKAwBLEkBGkUfHFMcDA8DDWBKFk8UKgUffwsCGwofRRIYBgAAATRLHU8FPhBTPgUCVBEaAFMDCBdtZzJGCRoXMR0fJkkDHRYBABdUGgEKRGwDGhoGfwgfLAZOEAAXFR8NSQMIVyVHWA0Lfx4aMQ1CVAMACgAARU4UTy9UWAAAfxsSNgdkMgwEAHkkGw8NTyEDKA4APgQaKwhCVBYdCh1UCB1HUi9MFk8TLGMfNg8LVAcXRRERCBsTSCZWFE8eNgIWfxobGQgXF1MSBQEQRDJQWA4cO0kXOggaHEUeDBgRSQ8SVTVOFk8eOggFOhpkNQkBClMXCBwCASFBFxoGfx4bPh1OHAQB
from Crypto.Util.strxor import strxor
import base64
import random
def enc(data, key):
key = (key * (len(data) / len(key) + 1))[:len(data)]
return strxor(data, key)
poem = open('poem.txt', 'r').read()
flag = "hctf{xxxxxxxxxxx}"
with open('cipher.txt', 'w') as f:
f.write(base64.b64encode(enc(poem, flag[5:-1])))
f.close()
题目描述:这是一首英文诗,但它是加密的。找到标志,并恢复它
类似维吉尼亚的变种
参考代码
def getCipher(file='cipher.txt'):
c=''.join(map(lambda x:x.strip(),open('cipher.txt').readlines())).decode('base_64')
cc= [ord(i) for i in c]
# print cc,len(cc)
return cc
def getKeyPool(cipher, stepSet, plainSet, keySet):
keyPool = dict()
for step in stepSet:
maybe = [None] * step
for pos in xrange(step):
maybe[pos] = []
for k in keySet:
flag = 1
for c in cipher[pos::step]:
if c ^ k not in plainSet:
flag = 0
if flag:
maybe[pos].append(k)
for posPool in maybe:
if len(posPool) == 0:
maybe = []
break
if len(maybe) != 0:
keyPool[step] = maybe
return keyPool
def calCorrelation(cpool):
frequencies = {"e": 0.12702, "t": 0.09056, "a": 0.08167, "o": 0.07507, "i": 0.06966,
"n": 0.06749, "s": 0.06327, "h": 0.06094, "r": 0.05987, "d": 0.04253,
"l": 0.04025, "c": 0.02782, "u": 0.02758, "m": 0.02406, "w": 0.02360,
"f": 0.02228, "g": 0.02015, "y": 0.01974, "p": 0.01929, "b": 0.01492,
"v": 0.00978, "k": 0.00772, "j": 0.00153, "x": 0.00150, "q": 0.00095,
"z": 0.00074}
relative = 0.0
total = 0
fpool = 'etaoinshrdlcumwfgypbvkjxqz'
total = sum(cpool.values()) # 总和应包括字母和其他可见字符
for i in cpool.keys():
if i in fpool:
relative += frequencies[i] * cpool[i] / total
return relative
def analyseFrequency(cfreq):
key = []
for posFreq in cfreq:
mostRelative = 0
for keyChr in posFreq.keys():
r = calCorrelation(posFreq[keyChr])
if r > mostRelative:
mostRelative = r
keychar = keyChr
key.append(keychar)
return key
def getFrequency(cipher, keyPoolList):
freqList = []
keyLen = len(keyPoolList)
for i in xrange(keyLen):
posFreq = dict()
for k in keyPoolList[i]:
posFreq[k] = dict()
for c in cipher[i::keyLen]:
p = chr(k ^ c)
posFreq[k][p] = posFreq[k][p] + 1 if p in posFreq[k] else 1
freqList.append(posFreq)
return freqList
def vigenereDecrypt(cipher, key):
plain = ''
cur = 0
ll = len(key)
for c in cipher:
plain += chr(c ^ key[cur])
cur = (cur + 1) % ll
return plain
def main():
ps = []
ks = []
ss = []
ps.extend(xrange(0xff))
ks.extend(xrange(0x20,0x80))
ss.extend(xrange(1, 50))
cipher = getCipher()
keyPool = getKeyPool(cipher=cipher, stepSet=ss, plainSet=ps, keySet=ks)
for i in keyPool:
freq = getFrequency(cipher, keyPool[i])
key = analyseFrequency(freq)
print ''.join(map(chr,key))
if __name__ == '__main__':
main()