Это незначительное изменение в части расшифровки вашего кода заставило его работать на меня:
textInput = str(input(">>> "))
# encrypted = textInput.encode() #this is incorrect!
encrypted = eval(textInput)
Вот что я получаю:
Для части шифрования:
>>> test message
b'>xB)\xf1\xc5I\xd6\xce\xfb\xcf\x83\xe2\xc5\x8f\xcfl\xb9\x0f\xa2\x13\xa5\xe1\x03\xf7p\xb3\x9c\xeb\r\xc1"\xf2\x17\x8b\xea\t\xed\xb2xG\xb7\r\xa9\xf8\x03eBD\xdd9>\xbe\xd1O\xe2\x9f\xbb\xf9\xff5\x96l\xea\x17FI\x8d\x02\x05\xea\x1dpM\xbb\x04J\xfc\x0c\\\xfe\x15\x07\xaf \x9e\xc2\xf9M\xa4\x1d$\xc3\x99my\xb6\xc5\xad\x97\xd06\xd2\x08\xd3\xe2\xc8H\xca\xd8\xfd{\xe6\xc6\xa3\x18\xeb\xe6\xcc\xc5\x9a\xc8*\xbb\xc1\x8c\x80,\x1f\r@\x9b\x9d\xc5\x91I\xa8\xc01y\xbc\xa73\xd3\x19;\xef\x8a\xfb\xc2\xc4\x9e\xbe\x8f\xeb\x1d\x12\xbd\xe4<\xa0\xbb\x8d\xef\xee\xa3\x89E\x07"m\x1d\xb0\xf3\xd2:y\xd9\xbd\xef\xdf\xc9\xbb\x1b\xd5\x03\x91\xa4l\x8bS\x9e\x80\x14\x90\x18\xc4\x9e\\?\x8eF\x05\xa1H\x9e:\x0c\x96\x8e\xb3E3\x90\xa2\xa1\xd9\x88\xa0<X\x7f\rIP\x00\xbf\xf6\x15\xfb9tW\x17\x9f\xca\x95\xf6|\xd7\x90\xbcp\xe5\xb5,V\x1b\xe9\x90\xf6\x87 v=6'
Теперь для расшифровки я использую вывод:
>>> b'>xB)\xf1\xc5I\xd6\xce\xfb\xcf\x83\xe2\xc5\x8f\xcfl\xb9\x0f\xa2\x13\xa5\xe1\x03\xf7p\xb3\x9c\xeb\r\xc1"\xf2\x17\x8b\xea\t\xed\xb2xG\xb7\r\xa9\xf8\x03eBD\xdd9>\xbe\xd1O\xe2\x9f\xbb\xf9\xff5\x96l\xea\x17FI\x8d\x02\x05\xea\x1dpM\xbb\x04J\xfc\x0c\\\xfe\x15\x07\xaf \x9e\xc2\xf9M\xa4\x1d$\xc3\x99my\xb6\xc5\xad\x97\xd06\xd2\x08\xd3\xe2\xc8H\xca\xd8\xfd{\xe6\xc6\xa3\x18\xeb\xe6\xcc\xc5\x9a\xc8*\xbb\xc1\x8c\x80,\x1f\r@\x9b\x9d\xc5\x91I\xa8\xc01y\xbc\xa73\xd3\x19;\xef\x8a\xfb\xc2\xc4\x9e\xbe\x8f\xeb\x1d\x12\xbd\xe4<\xa0\xbb\x8d\xef\xee\xa3\x89E\x07"m\x1d\xb0\xf3\xd2:y\xd9\xbd\xef\xdf\xc9\xbb\x1b\xd5\x03\x91\xa4l\x8bS\x9e\x80\x14\x90\x18\xc4\x9e\\?\x8eF\x05\xa1H\x9e:\x0c\x96\x8e\xb3E3\x90\xa2\xa1\xd9\x88\xa0<X\x7f\rIP\x00\xbf\xf6\x15\xfb9tW\x17\x9f\xca\x95\xf6|\xd7\x90\xbcp\xe5\xb5,V\x1b\xe9\x90\xf6\x87 v=6'
test message
Проблема с вашим исходным кодом состоит в том, что вы пишете представление строки байтов в качестве Unicode string (при использовании print(encrypted)
), затем кодирует его в байтовый объект в коде расшифровки, а затем передает его в функцию расшифровки. Кодирование этой строки не даст исходную строку байтов encrypted
.
Этот пример иллюстрирует проблему:
>>> x = bytes(bytearray.fromhex('f3'))
>>> x #A bytes string, similar to encrypt
b'\xf3'
>>> print(x)
b'\xf3'
>>> len(x)
1
>>> str(x) #this is what print(x) writes to stdout
"b'\\xf3'"
>>> print(str(x))
b'\xf3'
>>> len(str(x)) #Note that the lengths are different!
7
>>> x == str(x)
False
>>> str(x).encode() #what you were trying to do
b"b'\\xf3'"
>>> x == str(x).encode()
False
>>> eval(str(x)) #what gets the desired result
b'\xf3'
>>> x == eval(str(x))
True
Дело в том, что функция print
печатает представление объекта, а не сам объект. По сути, он делает это, получая значение для печати непечатаемых объектов, используя методы __repr__
или __str__
методов этого объекта.
Это документация для __str__
:
Вызывается str(object)
и встроенными функциями format()
и print()
для вычисления «неформального» или «приятного» печатное строковое представление объекта. Возвращаемое значение должно быть строковым объектом. , , Реализация по умолчанию, определяемая объектами встроенного типа, вызывает object.__repr__()
.
и __repr__
:
Вызывается встроенной функцией repr()
для вычислить «официальное» строковое представление объекта. Если это вообще возможно, это должно выглядеть как действительное выражение Python, которое можно использовать для воссоздания объекта
Это "официальное" представление, возвращаемое __repr__
, позволило мне использовать eval
функция в расшифровочном коде для решения проблемы.
TL; DR : копирование вывода print(encrypted)
копирует неофициальное, читаемое человеком значение, возвращаемое encrypted.__str__()
или "официальное" представление, возвращаемое encrypted.__repr__()
, которые находятся в удобочитаемой кодировке, такой как utf-8
. Они не могут быть закодированы обратно (с использованием кодировки utf-8
) для создания исходной строки байтов, которую они представляют.
Стоит также изучить этот вопрос от пользователя stackoverflow, обращенного к та же проблема. Ответ дает способ фактически закодировать это представление обратно в байтовый объект, если хотите. Это стоит посмотреть, потому что eval
следует избегать, это очень небезопасно . Для того, чтобы этот метод работал, вы должны были бы удалить начальную b'
и конечную '
из строки textInput
перед ее кодированием.
Моя последняя рекомендация - передать весь объект encrypted
между двумя программами, используя файлы с модулем pickle
, или какую-либо форму программирования сокетов. Лучше избегать использования print
и input
для передачи данных между программами во избежание проблем с кодировкой.