# this code cracks the caesar cipher
import re
from ngram_score import ngram_score

fitness = ngram_score('quadgrams.txt') # load our quadgram statistics

# helper function, converts an integer 0-25 into a character
def i2a(i): return 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[i%26]

# decipher a piece of text using the caesar cipher and a certain key        
def caesar_decipher(text,key):
    ret = ''
    for c in text:
        if c.isalpha(): ret += i2a( ord(c.upper()) - ord('A') - key )
        else: ret += c
    return ret

def break_caesar(ctext):
    # make sure ciphertext has all spacing/punc removed and is uppercase
    ctext = re.sub('[^A-Z]','',ctext.upper())
    scores = [(fitness.score(caesar_decipher(ctext,i)),i) for i in range(26)]
    return max(scores)
   
# example ciphertext
ctext = 'YMJHFJXFWHNUMJWNXTSJTKYMJJFWQNJXYPSTBSFSIXNRUQJXYHNUMJWX'
best_score,best_key = break_caesar(ctext)
    
print 'best candidate with key '+str(best_key)+':'
print caesar_decipher(ctext,best_key)    


