- Преобразование байтов в строку в Python
- Преобразование байтов в строку в Python 3
- Преобразование байтов в строку с помощью decode()
- Преобразование байтов в строку с кодеками
- Преобразование байтов в строку с помощью str()
- Преобразование байтов в строку в Python 2
- Преобразование байтов в Unicode (Python 2)
- Преобразование байтов в строку с помощью decode() (Python 2)
- Преобразование байтов в строку с помощью кодеков (Python 2)
- Помните о своей кодировке
- Перевод байтов в строки и обратно
- 2 примера для преобразования массива Byte [] в строку в Java
- Как преобразовать byte [] в строку в Java
- Конвертация между байтами и строками¶
- encode, decode¶
- str.encode, bytes.decode¶
- Как работать с Юникодом и байтами¶
- Преобразование из String в массив байтов и обратно
- 1 ответ 1
Преобразование байтов в строку в 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, но там используется каждый раз соль, которая итак рандомно генерит. И расшифровать таким образом не получится, если только не хранить соль в файле и подтягивать ее, но тогда безопасность ставится под вопрос. Источник Преобразование байтового массива в 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. Есть несколько способов изменить байтовый массив на String в Java, вы можете использовать методы из JDK или использовать бесплатные API с открытым исходным кодом, такие как Apache commons и Google Guava. Этот API предоставляет как минимум два набора методов для создания байтового массива формы String; один, который использует кодировку платформы по умолчанию, а другой — кодировку символов. Вы всегда должны использовать позже, не полагайтесь на кодировку платформы. Я знаю, что это может быть то же самое, или вы, возможно, не сталкивались с какими-либо проблемами, но лучше быть в безопасности, чем потом сожалеть. Как я указывал в своем последнем посте о печати байтового массива в виде шестнадцатеричной строки , это также один из лучших способов указания кодировки символов при преобразовании байтов в символы на любом языке программирования. Возможно, ваш байтовый массив содержит непечатаемые символы ASCII. Давайте сначала посмотрим, как JDK преобразует byte [] в 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: Если вы читаете байты из входного потока, вы также можете проверить мой предыдущий пост о 5 способах преобразования InputStream в String в Java для получения подробной информации. Источник Избежать работы с байтами нельзя. Например, при работе с сетью или файловой системой, чаще всего, результат возвращается в байтах. Соответственно, надо знать, как выполнять преобразование байтов в строку и наоборот. Для этого и нужна кодировка. Кодировку можно представлять как ключ шифрования, который указывает: Эта аналогия позволяет понять, что преобразования строка-байты и байты-строка должны использовать одинаковую кодировку. Для преобразования строки в байты используется метод encode: Чтобы получить строку из байт, используется метод decode: Метод encode есть также в классе str (как и другие методы работы со строками): А метод decode есть у класса bytes (как и другие методы): В этих методах кодировка может указываться как ключевой аргумент (примеры выше) или как позиционный: Есть очень простое правило, придерживаясь которого, можно избежать, как минимум, части проблем. Оно называется «Юникод-сэндвич»: This work is licensed under a CC-BY-SA-4.0. Источник Написал на Java следующую последовательность действий: Получаю из строки с кириллицей массив байтов Получается следующий массив: [-19, -18, -30, -32, -1, 32, -15, -14, -16, -18, -22, -32] Передаю его на вход классу ByteArrayOutputStream Выполняю обратное преобразование из массива байтов в строку Программа выводит в консоль текст новая строка Вопрос: так как кириллица в юникоде имеет кодепойнты, превышающие 1 тысячу (кодепойнт буквы А , к примеру, равен 1040), а байт в Java может принимать значения от -128 до 127, следовательно при попытке преобразовать строку в массив типа byte должна происходить потеря информации, как следствие — при вызове метода toString() строка должна восстановиться некорректно. Но этого не произошло. В чем тут причина? Это не юникод. 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: UTF-16BE: Для 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. Источник2 примера для преобразования массива Byte [] в строку в Java
Как преобразовать byte [] в строку в Java
Конвертация между байтами и строками¶
encode, decode¶
str.encode, bytes.decode¶
Как работать с Юникодом и байтами¶
Преобразование из String в массив байтов и обратно
1 ответ 1
Десятичное значение: 53437
Байты: 208 189
Десятичное значение: 1085
Байты: 4 61