Как перевести байты в текст python
Перейти к содержимому

Как перевести байты в текст python

  • автор:

Байты (bytes и bytearray)

Python 3 логотип

Байтовые строки в Python — что это такое и с чем это едят? Байтовые строки очень похожи на обычные строки, но с некоторыми отличиями. Попробуем выяснить, с какими.

Что такое байты? Байт — минимальная единица хранения и обработки цифровой информации. Последовательность байт представляет собой какую-либо информацию (текст, картинку, мелодию. ).

Создаём байтовую строку:

   
   Что делать с байтами? Хотя байтовые строки поддерживают практически все строковые методы, с ними мало что нужно делать. Обычно их надо записать в файл / прочесть из файла и преобразовать во что-либо другое (конечно, если очень хочется, то можно и распечатать). Для преобразования в строку используется метод decode:
 Bytearray в python - массив байт. От типа bytes отличается только тем, что является изменяемым. Про него, в общем-то, больше рассказать нечего.

Для вставки кода на Python в комментарий заключайте его в теги

Преобразование байтов в строку в Python

В этой статье мы рассмотрим, как преобразовать байты в строку в Python. К концу этой статьи у вас будет четкое представление о том, что это за типы и как эффективно обрабатывать данные с их помощью.

В зависимости от версии Python, которую вы используете, эта задача будет отличаться. Хотя Python 2 подошел к концу, многие проекты все еще используют его, поэтому мы включим оба подхода - Python 2 и Python 3.

Преобразование байтов в строку в Python 3

Начиная с Python 3, пришлось отказаться от старого способа работы с ASCII, и Python стал полностью Unicode.

Это означает, что мы потеряли явный тип Unicode: u"string" - каждая строка - это u"string" !

Чтобы отличить эти строки от старых добрых строк байтов, мы познакомились с новым спецификатором для них - b"string" .

Это было добавлено в Python 2.6, но не служило реальной цели, кроме подготовки к Python 3, поскольку все строки были байтовыми строками в 2.6.

Строки байтов в Python 3 официально называются bytes , неизменной последовательностью целых чисел в диапазоне 0

Преобразование байтов в строку с помощью decode()

Давайте посмотрим, как мы можем преобразовать байты в String, используя встроенный метод decode() для класса bytes :

b = b"Lets grab a \xf0\x9f\x8d\x95!" # Let's check the type print(type(b)) # # Now, let's decode/convert them into a string s = b.decode('UTF-8') print(s) # "Let's grab a ��!" 

Передав формат кодирования, мы преобразовали объект bytes в строку и распечатали ее.

Преобразование байтов в строку с кодеками

Как вариант, для этой цели мы можем использовать встроенный модуль codecs :

import codecs b = b'Lets grab a \xf0\x9f\x8d\x95!' print(codecs.decode(b, 'UTF-8')) # "Let's grab a ��!" 

Вам действительно не нужно передавать параметр кодировки, однако рекомендуется передавать его:

print(codecs.decode(b)) # "Let's grab a ��!" 
Преобразование байтов в строку с помощью str()

Наконец, вы можете использовать str() функцию, которая принимает различные значения и преобразует их в строки:

b = b'Lets grab a \xf0\x9f\x8d\x95!' print(str(b, 'UTF-8')) # "Let's grab a ��!" 

Не забудьте указать аргумент кодировки str() , иначе вы можете получить неожиданные результаты:

print(str(b)) # b'Lets grab a \xf0\x9f\x8d\x95!' 

Это снова подводит нас к кодировкам. Если вы укажете неправильную кодировку, в лучшем случае произойдет сбой вашей программы, потому что она не может декодировать данные. Например, если бы мы попытались использовать функцию str() с UTF-16 , нас бы встретили:

print(str(b, 'UTF-16')) # '敌❴\u2073牧扡愠\uf020趟↕' 

Это даже более важно, учитывая, что Python 3 любит использовать Unicode, поэтому, если вы работаете с файлами или источниками данных, которые используют непонятную кодировку, обязательно обратите на это особое внимание.

Преобразование байтов в строку в Python 2

В Python 2 набор байтов и строка - это практически одно и то же: строки - это объекты, состоящие из однобайтовых символов, что означает, что каждый символ может хранить 256 значений. Вот почему их иногда называют строками байтов.

Это замечательно при работе с байтовыми данными - мы просто загружаем их в переменную и готовы к печати:

s = "Hello world!" print(s) # 'Hello world!' print(len(s)) # 12

Однако использование символов Unicode в строках байтов немного меняет это поведение:

s = "Let's grab a ��!" print(s) # 'Lets grab a \xf0\x9f\x8d\x95!' # Where has the pizza gone to? print(len(s)) # 17 # Shouldn't that be 15? 
Преобразование байтов в Unicode (Python 2)

Здесь нам придется использовать тип Python 2 Unicode , который предполагается и автоматически используется в Python 3. В нем строки хранятся как последовательность кодовых точек, а не байтов.

Представляет собой байты \xf0\x9f\x8d\x95 , последовательность шестнадцатеричных чисел и Python не знает, как представить их в виде ASCII:

>>> u = u"Let's grab a ��!" u"Let's grab a \U0001f355!"" >>> u "Let's grab a ��!" # Yum. >>> len(u) 15 

Как вы можете видеть выше, строка Unicode содержит \U0001f355 - экранированный символ Unicode, который наш терминал распечатывает как кусок пиццы! Установить это было так же просто, как использовать спецификатор u перед значением байтовой строки.

Итак, как мне переключаться между ними?

Вы можете получить строку Unicode, расшифровав свою байтовую строку. Это можно сделать, создав объект Unicode, предоставив байтовую строку и строку, содержащую имя кодировки в качестве аргументов, или вызвав .decode(encoding) у байтовой строки.

Преобразование байтов в строку с помощью decode() (Python 2)

Вы также можете использовать codecs.encode(s, encoding) из модуля codecs .

>>> s = "Let's grab a \xf0\x9f\x8d\x95!" >>> u = unicode(s, 'UTF-8') >>> u "Let's grab a ��!" >>> s.decode('UTF-8') "Let's grab a ��!" 
Преобразование байтов в строку с помощью кодеков (Python 2)

Или, используя модуль codecs :

import codecs >>> codecs.decode(s, 'UTF-8') "Let's grab a ��!" 

Помните о своей кодировке

Здесь следует предостеречь - байты могут по-разному интерпретироваться в разных кодировках. Из- за того, что из коробки доступно около 80 различных кодировок, может быть нелегко узнать, есть ли у вас правильная!

s = '\xf8\xe7' # This one will let us know we used the wrong encoding >>> s.decode('UTF-8') UnicodeDecodeError: 'utf8' codec can't decode byte 0xf8 in position 0: invalid start byte # These two overlaps and this is a valid string in both >>> s.decode('latin1') øç s.decode('iso8859_5') јч 

Исходное сообщение было либо, øç либо јч , и оба кажутся допустимыми преобразованиями.

Перевод байтов в строки и обратно в байты

Author24 — интернет-сервис помощи студентам

Пишу для себя софт с простеньким интерфейсом с полем вывода (Python 3.8), который будет генерить рандомные пароли для различных соцсетей и тд. После генерации использую шифровщик из пакета Crypto и сохраняю набор байт в строку в файл таким образом:

1 2 3 4 5 6 7 8
from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad cipher = AES.new(entered_key.encode('utf-8'), AES.MODE_ECB) pass = str(cipher.encrypt(pad(generated_password.encode('utf-8'), BLOCK_SIZE))) input = "resource^login^pass".

где entered_key - введенный пользователем ключ-"сид", по которому можно будет потом декодировать, generated_pass - результат выполнения генерации пароля в строковом формате (напр. "p5

В pass'е хранится строка из зашифрованного в байтах пароля.

В текстовом файле оно хранится в таком виде:

input = VK^my_email@gmail.com^b'\xe4>\x1dN\x90\xe2H5\xce\xa8\xb8\x85\x03\x86\x17\xa6\x05\x01\x87\xa0\xcd\xe5\xa9\x87,\xba\xb0\x91\xabs\xe5S'

Потом я начал думать над тем, как это расшифровывать и выводить на экран. В итоге долгие попытки танцев с бубном над кодировками и у меня ни черта не получилось. То есть проблема состоит в том, чтобы из строковой переменной, в которой хранится байтовое представление пароля, сделать ее байтовой, декодировать и вывести на экран как строку.

На выходе я открываю файл, в котором сохранил строку, спличу ее по '^' и достаю элемент с индексом 2, т.е. - достаю pass. А потом я уже стараюсь что-нибудь сделать, чтобы расшифровать:

1 2 3
decipher = AES.new(entered_key.encode('utf-8'), AES.MODE_ECB) text = openfile.read().split('^') pass = text[2]

Теперь в pass'e мы имеем строку:

pass = "b'\xe4>\x1dN\x90\xe2H5\xce\xa8\xb8\x85\x03\x86\x17\xa6\x05\x01\x87\xa0\xcd\xe5\xa9\x87,\xba\xb0\x91\xabs\xe5S'"

И вот надо как-то эту строку перевести правильно в байты, чтобы можно было использовать следующее:

decrypted_pass = decipher.decrypt(pass) unpadded_decrypted_pass=unpad(decrypted_pass, BLOCK_SIZE)

Я пробовал преобразовывать эту строку pass разными способами:

1 2 3 4 5 6 7
bytes_pass = bytes(pass, encoding='utf-8') bytes_pass = pass[2:-1].encode('utf-8') #делаю срез, чтобы не было в начале b' и в конце ' bytes_pass = pass.encode('utf-8') bytes_pass = bytes(map(ord, pass))

и другие варианты.

И ничего из этого не давало мне нужного результата. В некоторых случаях у меня в переменной bytes_pass хранилось:

b"b'\\xe4>\\x1dN\\x90\\xe2H5\\xce\\xa8\\xb8\\x85\\x03\\x86\\x17\\xa6\\x05\\x01\\x87\\xa0\\xcd\\xe5\\xa9\\x87,\\xba\\xb0\\x91\\xabs\\xe5S'"
b'\\xe4>\\x1dN\\x90\\xe2H5\\xce\\xa8\\xb8\\x85\\x03\\x86\\x17\\xa6\\x05\\x01\\x87\\xa0\\xcd\\xe5\\xa9\\x87,\\xba\\xb0\\x91\\xabs\\xe5S'

Если у кого-то есть идеи, как это можно грамотно обработать, чтобы получить в итоге исходную записанную в файл рандомно сгенерированную строку, то велкам. Либо может у кого-то есть решение проблемы кодирования любой строки по какому-то ключу (знаете, как в играх с процедурной генерацией, то есть каждый мог бы поиграть на той же карте, что и другой, если у него есть ключ(сид), вот только зашифровать и расшифровывать по нему), сохранением в текстовый файл с возможностью достать это и расшифровать обратно. Я пробовал использовать также и fernet, но там используется каждый раз соль, которая итак рандомно генерит. И расшифровать таким образом не получится, если только не хранить соль в файле и подтягивать ее, но тогда безопасность ставится под вопрос.

94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Перевод структур в байты и обратно
Всем здравствуйте. Тема вытекла из https://www.cyberforum.ru/vb-net/thread1775855.html Imports.

Перевод Байтов в биты и обратно
Всем Привет. Помогите пожалуйста написать алгоритм перевода байтов в биты и обратно Допустим водим.

Перевод байтов в сетевой порядок и обратно
Вообщем нужно переводить массив байтов, сделал так : union bits < unsigned int number; .

Чтение массива байтов из файла, если байты в файле начинаются с определенной строки
Всем здравствуйте. Такая проблема. Есть файл, в который записаны некоторые текстовые данные, и с n.

Перевод чисел в строки и обратно
Здравствуйте. Суть в чём - надо считать с текстового файла матрицу чисел, перевести её в строки.

Конвертация между байтами и строками#

Избежать работы с байтами нельзя. Например, при работе с сетью или файловой системой, чаще всего, результат возвращается в байтах.

Соответственно, надо знать, как выполнять преобразование байтов в строку и наоборот. Для этого и нужна кодировка.

Кодировку можно представлять как ключ шифрования, который указывает:

  • как «зашифровать» строку в байты (str -> bytes). Используется метод encode (похож на encrypt)
  • как «расшифровать» байты в строку (bytes -> str). Используется метод decode (похож на decrypt)

Эта аналогия позволяет понять, что преобразования строка-байты и байты-строка должны использовать одинаковую кодировку.

encode, decode#

Для преобразования строки в байты используется метод encode:

In [1]: hi = 'привет' In [2]: hi.encode('utf-8') Out[2]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [3]: hi_bytes = hi.encode('utf-8') 

Чтобы получить строку из байт, используется метод decode:

In [4]: hi_bytes Out[4]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [5]: hi_bytes.decode('utf-8') Out[5]: 'привет' 

str.encode, bytes.decode#

Метод encode есть также в классе str (как и другие методы работы со строками):

In [6]: hi Out[6]: 'привет' In [7]: str.encode(hi, encoding='utf-8') Out[7]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' 

А метод decode есть у класса bytes (как и другие методы):

In [8]: hi_bytes Out[8]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [9]: bytes.decode(hi_bytes, encoding='utf-8') Out[9]: 'привет' 

В этих методах кодировка может указываться как ключевой аргумент (примеры выше) или как позиционный:

In [10]: hi_bytes Out[10]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [11]: bytes.decode(hi_bytes, 'utf-8') Out[11]: 'привет' 

Как работать с Юникодом и байтами#

Есть очень простое правило, придерживаясь которого, можно избежать, как минимум, части проблем. Оно называется «Юникод-сэндвич»:

  • байты, которые программа считывает, надо как можно раньше преобразовать в Юникод (строку)
  • внутри программы работать с Юникод
  • Юникод надо преобразовать в байты как можно позже, перед передачей

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *