"""
Каждый символ в компьютере имеет уникальный код, предпочитаемым является
стандарт ASCII (American Standard Code for Information Interchange -
Американский стандартный код для обмена информацией). Для примера, A
верхнего регистра = 65, звездочка (*) = 42, а k нижнего регистра = 107.

Современный метод шифровки состоит в том, что берется текстовый файл,
конвертируется в байты по ASCII, а потом над каждым байтом выполняется
операция XOR с определенным значением, взятым из секретного ключа.
Преимущество функции XOR состоит в том, что применяя тот же ключ к
зашифрованному тексту, получается исходный; к примеру, 65 XOR 42 = 107,
тогда 107 XOR 42 = 65.

Для невзламываемого шифрования ключ должен быть такой же длины, что и сам
текст, и ключ должен быть составлен из случайных байтов. Тогда, если
пользователь хранит зашифрованное сообщение и ключ шифрования в разных
местах, то без обеих "половинок" расшифровать сообщение просто невозможно.

К сожалению, этот метод непрактичен для большинства пользователей, поэтому
упрощенный метод использует в качестве ключа пароль. Если пароль короче
текстового сообщения, что наиболее вероятно, то ключ циклично повторяется
на протяжении всего сообщения. Идеальный пароль для этого метода достаточно
длинный, чтобы быть надежным, но достаточно короткий, чтобы его можно было
запомнить.

Ваша задача была упрощена, так как пароль состоит из трех символов нижнего
регистра. Используя p059_cipher.txt, содержащий зашифрованные коды ASCII,
а также тот факт, что сообщение должно содержать распространенные
английские слова, расшифруйте сообщение и найдите сумму всех
значений ASCII в исходном тексте.
"""
from itertools import cycle, permutations
import string

with open('p059_cipher.txt') as file:
    text = list(map(int, file.read().split(',')))

for keys in permutations(string.ascii_lowercase, 3):
    keys = [ord(let) for let in keys]
    desc_text = ''.join([chr(let ^ key) for let, key in zip(text, cycle(keys))])
    if 'the' in desc_text and 'it' in desc_text and 'have' in desc_text:
        print(sum([ord(let) for let in desc_text]))
        break

