In [1]:
def encrypt(text, shift):
    
    import string
    Alphabet = string.ascii_lowercase
    alphabet = string.ascii_uppercase
    hidden_Alphabet = Alphabet[shift:]+Alphabet[:shift]
    hidden_alphabet = alphabet[shift:]+alphabet[:shift]
    text_enc = text.translate(str.maketrans(Alphabet+alphabet,
                                            hidden_Alphabet+hidden_alphabet))
    return text_enc

def normalize(text):
    import re    
    text = re.sub(r'[^a-zA-Z]', '', text.lower())
    return text

def get_letter_freq(text):
    from collections import Counter
    import string
    norm_text = normalize(text)
    len_norm_text = len(norm_text)
    counts = dict(Counter([i for i in norm_text]))
    for char in string.ascii_lowercase:
        if char not in counts.keys():
            counts[char] = 0    
        counts[char] = counts[char]/len_norm_text
    
    return counts

def decrypt(chiffre, letter_freq=None):
    
    from collections import Counter
    
    if letter_freq == None:
        english_letter_freq = {'e': 12.70, 't': 9.06, 'a': 8.17, 'o': 7.51, 
                             'i': 6.97, 'n': 6.75, 's': 6.33, 'h': 6.09, 
                             'r': 5.99, 'd': 4.25, 'l': 4.03, 'c': 2.78, 
                             'u': 2.76, 'm': 2.41, 'w': 2.36, 'f': 2.23, 
                             'g': 2.02, 'y': 1.97, 'p': 1.93, 'b': 1.29, 
                             'v': 0.98, 'k': 0.77, 'j': 0.15, 'x': 0.15, 
                             'q': 0.10, 'z': 0.07}
        letter_freq = english_letter_freq
    
    
    
    chiffre_letter_freq = get_letter_freq(chiffre)
    
    sorted_chiffre_letter_freq = sorted(chiffre_letter_freq.items(), key=lambda x: x[1], reverse=True)
    sorted_letter_freq = sorted(letter_freq.items(), key=lambda x: x[1], reverse=True)
    
    alphabet = ''.join([x[0] for x in sorted_letter_freq])
    hidden_alphabet = ''.join([x[0] for x in sorted_chiffre_letter_freq])

    text = chiffre.translate(str.maketrans(hidden_alphabet+hidden_alphabet.upper(),
                                           alphabet+alphabet.upper()))
    return text

In [2]:
with open('sherlock.txt') as myfile:
    text = myfile.read()


encrypted = encrypt(text,1)

print(text[:38])
print(encrypted[:38])
print(decrypt(encrypted)[:38])


The Boscombe Valley Mystery 5, there's
Uif Cptdpncf Wbmmfz Nztufsz 5, uifsf't
Tie Pohwoupe Vallef Ufhterf 5, tiere'h

In [4]:
print(text[:38])
print(encrypted[:38])
print(decrypt(encrypted, get_letter_freq(text[:30000]))[:38])


The Boscombe Valley Mystery 5, there's
Uif Cptdpncf Wbmmfz Nztufsz 5, uifsf't
The Boswombe Valley Mystery 5, there's