Я преобразовал байтовый объект в str с помощью str (), как я могу преобразовать его обратно? - PullRequest
0 голосов
/ 02 февраля 2019

Я преобразовал некоторые китайские символы в UTF-8 в строковом объекте для некоторых операций.Теперь у меня возникает проблема, когда я пытаюсь преобразовать строковый объект обратно в байтовый объект.

Я пытался использовать bytes():

a = '一'
bytes_value = a.encode('utf-8') 
string_value = str(b)
bytes_value_again = bytes(string_value)

Я хочу преобразовать его обратно в байтыобъект, поэтому я могу использовать decode('utf-8'), чтобы преобразовать его обратно в оригинальные китайские символы.

1 Ответ

0 голосов
/ 02 февраля 2019

Вы не должны конвертировать bytes объекты в строки с str(bytes_value).Вы создали печатаемое представление объекта .

. Правильный способ преобразования из bytes в str состоит в декодировании байтов в Unicode.Если у вас есть байты UTF-8, декодируйте этот кодек с помощью bytes.decode() метода :

string_value = bytes_value.decode('utf8')

Вы можете также указать кодировку, если хотитеиспользуйте функцию str(), см. форму str(bytes_value, encoding) в документации :

string_value = str(bytes_value, 'utf8')

Если вы случайно использовали str(bytes_value) и теперь не можете получить исходное значение путем исправленияЭта ошибка и повторно запустив ваш код, вы можете восстановить исходное значение, используя ast.literal_eval():

bytes_representation = str(bytes_value)  # "b'....'"
recovered_bytes_value = ast.literal_eval(bytes_representation)

Это должно использоваться только для восстановления данных, а не какмеханизм сериализации на уровне производства .ast.literal_eval() довольно медленный и не защищен от атак типа «отказ в обслуживании», когда используется на вводе пользователем (возможно сбой Python или значительное замедление при неправильном вводе).

Если выиспользуя API, который действительно должен работать с байтами, но по какой-то причине принимает только строки (обычно это предупреждающий знак неправильно спроектированного и реализованного API), затем либо используйте кодировку двоичного кода в ASCII (включая base64 / base16 / base32 / base85 ) или декодируйте двоичные данные как Latin-1.

Это еще более важно, если вы делаете это для шифрования данных.Печатное представление объекта bytes() всегда использует только символы ASCII, всегда начинается с b' или b" и всегда заканчивается ' или ".Любые непечатаемые байты (более половины всех 256 возможных байтовых значений) представлены в ограниченном диапазоне \x{hh} и \{l} escape-последовательностей .Все это позволяет решительному злоумышленнику намного легче взломать ваше шифрование.Передовая библиотека шифрования позволит вам напрямую шифровать bytes.Фактически, обычно предпочтительнее для шифрования байтов.

...