# cyclically throughout the message. The balance for this method is # using a sufficiently long password key for security, but short enough # to be memorable. # # Your task has been made easy, as the encryption key consists of three # lower case characters. Using cipher1.txt (right click and 'Save # Link/Target As...'), a file containing the encrypted ASCII codes, and # the knowledge that the plain text must contain common English words, # decrypt the message and find the sum of the ASCII values in the # original text. from operator import xor from itertools import chain from euler import alphabet, combinations def decipher(cipher, key): for idx,c in enumerate(cipher): yield ord(key[idx % len(key)]) ^ c def text(ascii): return ''.join(map(chr, ascii)) keys = ( ''.join(t).lower() for t in combinations(alphabet, 3) ) ciphertext = map(int,open('cipher1.txt').read().split(',')) for k in keys: t = text(decipher(ciphertext, k)) if 'that' in t.lower() and 'the' in t.lower(): print sum(map(ord, t))
def replaceLocations(n, m): assert (m < n) for p in euler.combinations(range(n + 1), m): yield p
def replaceLocations(n,m): assert(m < n) for p in euler.combinations(range(n+1),m): yield p
def combine(dig, reploc, repval): digseq = euler.intToSeq(dig) seqn = len(digseq) + len(reploc) j = 0 res = [None for i in range(seqn)] for i in range(seqn): if i in reploc: res[i] = repval else: res[i] = digseq[j] j += 1 if res[0] == 0: return None return res def getPrimes(dig, reploc): vals = [combine(dig, reploc, repval) for repval in range(10)] # filter leading zeros vals = [v for v in vals if v != None] vals = [euler.seqToInt(v) for v in vals] vals = [v for v in vals if euler.isprime(v)] return vals for dig in digits(3): for c in euler.combinations(range(6), 3): n = getPrimes(dig, c) if len(n) >= 8: print len(n), n
yield p def combine( dig, reploc, repval ): digseq = euler.intToSeq(dig) seqn = len(digseq) + len(reploc) j = 0 res = [ None for i in range(seqn) ] for i in range(seqn): if i in reploc: res[i] = repval else: res[i] = digseq[j] j += 1 if res[0] == 0: return None return res def getPrimes( dig, reploc ): vals = [ combine(dig,reploc,repval) for repval in range(10) ] # filter leading zeros vals = [ v for v in vals if v != None ] vals = [ euler.seqToInt(v) for v in vals ] vals = [ v for v in vals if euler.isprime(v) ] return vals for dig in digits(3): for c in euler.combinations(range(6),3): n = getPrimes( dig, c ) if len(n) >= 8: print len(n),n