Как вывести байт строку

Преобразование байтов в строку в 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 bytes — подобный объект, добавленный в 2.6, bytearray — похож на bytes , но изменяемый.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Преобразование байтов в Unicode (Python 2)

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

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

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

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

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

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

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

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

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

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

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

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

Источник

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

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

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

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

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

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

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

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

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

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

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

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

Источник

2 примера для преобразования массива Byte [] в строку в Java

Преобразование байтового массива в String кажется простым, но трудно сделать это правильно. Многие программисты делают ошибку, игнорируя кодировку символов всякий раз, когда байты преобразуются в String или char или наоборот. Как программист, мы все знаем, что компьютер понимает только двоичные данные, то есть 0 и 1. Все, что мы видим и используем, например изображения, текстовые файлы, фильмы или любые другие мультимедийные файлы, хранится в виде байтов, но что более важно это процесс кодирования или декодирования байтов в символ. Преобразование данных является важной темой на любом собеседовании по программированию, и из-за хитрости кодирования символов эти вопросы являются одним из самых популярных вопросов о интервью в формате String в интервью Java. При чтении строки из входного источника, например, файлов XML, HTTP-запроса, сетевого порта или базы данных, вы должны обратить внимание на то, какую кодировку символов (например, UTF-8, UTF-16 и ISO 8859-1) они кодируют. Если вы не будете использовать ту же кодировку символов при преобразовании байтов в строку , вы получите поврежденную строку, которая может содержать совершенно неправильные значения. Вы могли видеть ?, квадратные скобки после преобразования byte [] в String, это из-за значений, которые ваша текущая кодировка символов не поддерживает, и просто показывает некоторые значения мусора.

Я пытался понять, почему программы делают ошибки кодирования символов чаще, чем нет, и мои небольшие исследования и собственный опыт позволяют предположить, что это может быть вызвано двумя причинами: во-первых, недостаточно для интернационализации и кодировки символов, а во-вторых, потому что символы ASCII поддерживаются почти все популярные схемы кодирования и имеют одинаковые значения. Поскольку мы в основном имеем дело с кодировкой, такой как UTF-8, Cp1252 и Windows-1252, которая отображает символы ASCII (в основном алфавиты и цифры) без сбоев, даже если вы используете другую схему кодирования. Настоящая проблема возникает, когда ваш текст содержит специальные символы, например «é» , который часто используется во французских именах. Если кодировка символов вашей платформы не распознает этот символ, то либо вы увидите другой символ, либо что-то в этом роде, и, к сожалению, пока вы не обожгете руки, вы вряд ли будете осторожны с кодировкой символов. В Java все немного сложнее, потому что многие классы ввода-вывода, например InputStreamReader, по умолчанию используют кодировку символов платформы. Это означает, что если вы запустите свою программу на другом компьютере, вы, скорее всего, получите другой вывод из-за разного кодирования символов, используемого на этом компьютере. В этой статье мы узнаем, как преобразовать byte [] в String в Java как с помощью JDK API, так и с помощью общих утилит Guava и Apache.

Как преобразовать byte [] в строку в Java

Есть несколько способов изменить байтовый массив на String в Java, вы можете использовать методы из JDK или использовать бесплатные API с открытым исходным кодом, такие как Apache commons и Google Guava. Этот API предоставляет как минимум два набора методов для создания байтового массива формы String; один, который использует кодировку платформы по умолчанию, а другой — кодировку символов. Вы всегда должны использовать позже, не полагайтесь на кодировку платформы. Я знаю, что это может быть то же самое, или вы, возможно, не сталкивались с какими-либо проблемами, но лучше быть в безопасности, чем потом сожалеть. Как я указывал в своем последнем посте о печати байтового массива в виде шестнадцатеричной строки , это также один из лучших способов указания кодировки символов при преобразовании байтов в символы на любом языке программирования. Возможно, ваш байтовый массив содержит непечатаемые символы ASCII. Давайте сначала посмотрим, как JDK преобразует byte [] в String:

  1. Вы можете использовать конструктор String, который принимает байтовый массив и кодировку символов:

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

Если вы читаете байтовый массив из любого текстового файла, например, XML-документа, HTML-файла или двоичного файла, вы можете использовать библиотеку Apache Commons IO для непосредственного преобразования FileInputStream в строку. Этот метод также буферизует входные данные для внутреннего использования, поэтому нет необходимости использовать другой BufferedInputStream .

Чтобы правильно преобразовать этот байтовый массив в строку, вы должны сначала обнаружить правильную кодировку символов, прочитав метаданные, например Content-Type, и т. Д., В зависимости от формата / протокола данных, которые вы читаете. , Это одна из причин, по которой я рекомендую использовать парсеры XML, например парсеры SAX или DOM, для чтения XML-файлов, они сами занимаются кодированием символов.

Некоторые программисты также рекомендуют использовать Charset over String для определения кодировки символов, например, вместо «UTF-8» используйте StandardCharsets.UTF_8, главным образом, чтобы избежать исключения UnsupportedEncodingException в худшем случае. Существует шесть стандартных реализаций Charset, которые гарантированно поддерживаются всеми реализациями платформы Java. Вы можете использовать их вместо указания схемы кодирования в String. Короче говоря, всегда предпочитайте StandardCharsets.ISO_8859_1 вместо «ISO_8859_1», как показано ниже:

Другие стандартные кодировки, поддерживаемые платформой Java:

  1. StandardCharsets.ISO_8859_1
  2. StandardCharsets.US_ASCII
  3. StandardCharsets.UTF_16
  4. StandardCharsets.UTF_16BE
  5. StandardCharsets.UTF_16LE

Если вы читаете байты из входного потока, вы также можете проверить мой предыдущий пост о 5 способах преобразования InputStream в String в Java для получения подробной информации.

Источник

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

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

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

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

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

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

encode, decode¶

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

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

str.encode, bytes.decode¶

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

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

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

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

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

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

This work is licensed under a CC-BY-SA-4.0.

Источник

Преобразование из String в массив байтов и обратно

Написал на Java следующую последовательность действий:

Получаю из строки с кириллицей массив байтов

Получается следующий массив:

[-19, -18, -30, -32, -1, 32, -15, -14, -16, -18, -22, -32]

Передаю его на вход классу ByteArrayOutputStream

Выполняю обратное преобразование из массива байтов в строку

Программа выводит в консоль текст новая строка

Вопрос: так как кириллица в юникоде имеет кодепойнты, превышающие 1 тысячу (кодепойнт буквы А , к примеру, равен 1040), а байт в Java может принимать значения от -128 до 127, следовательно при попытке преобразовать строку в массив типа byte должна происходить потеря информации, как следствие — при вызове метода toString() строка должна восстановиться некорректно. Но этого не произошло. В чем тут причина?

1 ответ 1

Это не юникод. String.getBytes() использует кодировку по-умолчанию платформы:

Encodes this String into a sequence of bytes using the platform’s default charset, storing the result into a new byte array.

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

Для получения байтов в юникоде, задайте кодировку явно:

Получится больше 12 байтов.

Обновление по вопросам в комментарии:

Разве UTF-8 выдает байты, эквивалентные юникодовскому представлению?

У юникода бывают разные представления. UTF-8 — одно из них.

Я знаю, что char выдает кодепойнты юникода. Если вывести System.out.println((byte)’н’), то это будет равно 61.

Здесь можно посмотреть как строчная кириллическая «н» представляется в разных кодировках: https://unicode-table.com/en/043D/

UTF-8:
Десятичное значение: 53437
Байты: 208 189

UTF-16BE:
Десятичное значение: 1085
Байты: 4 61

Для char в Java, согласно спецификации (§3.1 Unicode) используется кодировка UTF-16. Это тоже двухбайтовая кодировка. Соответственно, когда Вы приводите char к byte Вы получаете младший байт в этой кодировке.

Получить байты в «UTF-16BE» можно так:

Если вывести байты, как Вы предложили byte[] bytes=»новая строка».getBytes(«UTF-8»), то там первый байт равен -48, а не 61.

Кодировка UTF-8, как указано ранее беззнаковые (от 0 до 255) байты: 208 и 189. Знаковые байты, соответственно, -48 и -67.

Источник

Оцените статью