Кодирование текста в произвольный двоичный код и обратно. Пример: «А» «01100011»
Мне нужно преобразовать строку, например «А» , в строку двоичного кода, например «01100011» , потом обработать немного двоичный код, пропустив его по функции «Исключающее ИЛИ» с другим двоичным кодом, например «01100011» с «11000010» , тогда выйдет «10100001» , и обратно перевести получившийся код в читаемую строку, например в «Т» . При этом, я хочу использовать русскую, английскую и украинскую раскладку и цифры, со знаками припинания. Не подскажете, как это сделать на Python 3? Вопрос состоит в том как в Python преобразовать строку в двоичный код и обратно используя любой алгоритм кодировки?
Отслеживать
16.5k 4 4 золотых знака 19 19 серебряных знаков 30 30 бронзовых знаков
задан 7 сен 2017 в 17:12
191 1 1 золотой знак 2 2 серебряных знака 11 11 бронзовых знаков
Вы можете привести пример входной и выходной строк и алгоритм получения ‘T’ из «11000010» ?
7 сен 2017 в 17:19
Нет, алгоритм кодировки может быть любым, хоть МТК-2 🙂 Мне нужны функции, которые быстро переведут текст в двоичный код, любым способом!
7 сен 2017 в 17:25
Т.е. вопрос состоит в том как в Python преобразовать строку в двоичный код и обратно используя любой алгоритм кодировки? 😉
7 сен 2017 в 17:29
Да, именно это мне и требуется)
7 сен 2017 в 18:11
7 сен 2017 в 21:35
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Чтобы произвольный текст превратить в «01»-строки (биты):
def text_to_bits(text, encoding='utf-8', errors='surrogatepass'): bits = bin(int.from_bytes(text.encode(encoding, errors), 'big'))[2:] return bits.zfill(8 * ((len(bits) + 7) // 8))
def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'): n = int(bits, 2) return n.to_bytes((n.bit_length() + 7) // 8, 'big').decode(encoding, errors) or '\0'
>>> text_to_bits("мiр"))) '1101000010111100011010011101000110000000' >>> text_from_bits(_) мiр
Чтобы выполнить XOR над двумя строками, нет необходимости биты в виде ascii-строк выражать:
from itertools import cycle def xor(message, key): return bytes(a^b for a, b in zip(message, cycle(key)))
Достаточно текст в байты закодировать, используя .encode() метод:
>>> key = b'key' >>> xor('hello world'.encode(), key) b'\x03\x00\x15\x07\nY\x1c\n\x0b\x07\x01' >>> xor(_, key).decode() # и обратно 'hello world'
Для больших строк, можно numpy использовать:
import numpy as np # pip install numpy def slow_xor(aa, bb): a = np.frombuffer(aa, dtype=np.byte) b = np.frombuffer(bb, dtype=np.byte) return np.bitwise_xor(a, b).tostring()
>>> slow_xor(b'hello. ', 'миръ'.encode()) b'\xb8\xd9\xbc\xd4\xbe\xae\xff\xa4'
Отслеживать
ответ дан 7 сен 2017 в 22:15
52.3k 11 11 золотых знаков 108 108 серебряных знаков 312 312 бронзовых знаков
Спасибо большое за ответ! Но как перевести «b’\xb8\xd9\xbc\xd4\xbe\xae\xff\xa4′» в «читаемую» строку?
8 сен 2017 в 16:03
@Nazar: не всякий набор байт является текстом (представьте данные картинки, пожатого архива). Если сделать XOR двух случайных фрагметов текста, закодированных в байты, используя какую-нибудь кодировку, то результат не обязан быть текстом в какой-либо ни было кодировке. Считайте XOR операцией шифрования, если ‘миръ’ это ключ, то чтобы расшифровать (достать исходный текст), можно снова XOR применить: xor(b’\xb8\xd9\xbc\xd4\xbe\xae\xff\xa4′, ‘миръ’.encode()).decode() -> ‘hello. ‘
8 сен 2017 в 17:20
Я тоже так думал. Пока не попробывал сделать это! Оказалось, что для xor нужно чтобы были одинаковые длины. А у b’\xb8\xd9\xbc\xd4\xbe\xae\xff\xa4′ и b’миръ’ длины разные! Поэтому обратно не получается получить изначальный текст.
9 сен 2017 в 11:18
@Nazar: длина одинаковая: 8 байт ( len(‘миръ’.encode()) == 8 ). b’миръ’ это вообще SyntaxError (код для Питон 3, так как вопрос имеет метку python-3.x). Верно, что размер для xor одинаковый нужен (поэтому cycle(key) и используется в одной из реализаций — не используйте для секретов)
9 сен 2017 в 14:26
Да, спасибо, я уже разобрался, проблема у меня была) Спасибо большое за помощь 🙂
9 сен 2017 в 17:44
s = 'отака собі тестова - String !' def encode(s): return list(map(lambda x: "".format(ord(x)).zfill(16), s)) def decode(lst): return ''.join(map(lambda x: chr(int(x,2)), lst))
In [10]: lst = encode(s) In [11]: lst Out[11]: ['0000010000111110', '0000010001000010', '0000010000110000', '0000010000111010', '0000010000110000', '0000000000100000', '0000010001000001', '0000010000111110', '0000010000110001', '0000010001010110', '0000000000100000', '0000010001000010', '0000010000110101', '0000010001000001', '0000010001000010', '0000010000111110', '0000010000110010', '0000010000110000', '0000000000100000', '0000000000101101', '0000000000100000', '0000000001010011', '0000000001110100', '0000000001110010', '0000000001101001', '0000000001101110', '0000000001100111', '0000000000100000', '0000000000100001'] In [12]: decode(lst) Out[12]: 'отака собі тестова - String !'
Python-сообщество
![]()
- Начало
- » Python для новичков
- » Бинарный Код в текст
#1 Ноя. 7, 2010 12:35:28
FewG От: Зарегистрирован: 2010-11-07 Сообщения: 19 Репутация: 0 Профиль Отправить e-mail
Бинарный Код в текст
Подскажите, как можно Бинарный Код перевести в текст (Unicode).
#2 Ноя. 7, 2010 12:57:00
regall От: Киев Зарегистрирован: 2008-07-17 Сообщения: 1583 Репутация: 3 Профиль Отправить e-mail
Бинарный Код в текст
Подскажите, как можно Бинарный Код перевести в текст (Unicode).
Что вы имеете в виду под “бинарным кодом”, и где это хранится?
Если это тип bytes — то
>>> us = "This is a строка"
>>> bs = us.encode('utf-8') # Это уже байты
>>> bs
b'This is a \xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0'
>>> bs.decode('utf-8') # И опять строка
'This is a строка'
#3 Ноя. 7, 2010 12:59:47
FewG От: Зарегистрирован: 2010-11-07 Сообщения: 19 Репутация: 0 Профиль Отправить e-mail
Бинарный Код в текст
Я про перевод бинарного кода (к примеру: 00101010 00101110 00101010 (т.е. Блоков по 8 бит))в текст *.*
#4 Ноя. 7, 2010 13:04:22
regall От: Киев Зарегистрирован: 2008-07-17 Сообщения: 1583 Репутация: 3 Профиль Отправить e-mail
Бинарный Код в текст
FewG
Я про перевод бинарного кода (к примеру: 00101010 00101110 00101010 (т.е. Блоков по 8 бит))в текст *.*
В какой форме хранятся исходные данные?
#5 Ноя. 7, 2010 13:13:07
FewG От: Зарегистрирован: 2010-11-07 Сообщения: 19 Репутация: 0 Профиль Отправить e-mail
Бинарный Код в текст
ммм, ни в какой; Пользователь вводит код в ручную, далее этот код должен быть переведен (переконвертирован) в текст. Я новичек, даже не знаю как точно описать всё это.
#6 Ноя. 7, 2010 15:07:56
pill От: Зарегистрирован: 2010-08-27 Сообщения: 223 Репутация: 0 Профиль Отправить e-mail
Бинарный Код в текст
FewG
ммм, ни в какой; Пользователь вводит код в ручную, далее этот код должен быть переведен (переконвертирован) в текст. Я новичек, даже не знаю как точно описать всё это.
Насколько я понимаю int в ascii требуеться.
как то так можно.
Ток разбивку нужно будет добавить чтоб не по одному байту вбивать.
bin_str = raw_input("Please enter a binary number ")
#Конвертим введенную Строку вида (1001010) в intRJydthnbv
num = int(bin_str, 2)
#Конвертим в int в char
char_ascii = chr(num)
print char_ascii
#7 Ноя. 7, 2010 15:19:07
regall От: Киев Зарегистрирован: 2008-07-17 Сообщения: 1583 Репутация: 3 Профиль Отправить e-mail
Бинарный Код в текст
FewG
ммм, ни в какой; Пользователь вводит код в ручную, далее этот код должен быть переведен (переконвертирован) в текст. Я новичек, даже не знаю как точно описать всё это.
Ну, с этим разобрались. Код вводится с клавиатуры, то есть исходными данными является строка. Я полагаю вам нужно превратить этот код в символы в некоторой кодировки.
Тогда примерно так:
>>> result = ''
>>> input_string = input('Enter binary code: ')
Enter binary code: 101011 11001 10101
>>> for word in input_string.strip().split(' '):
. number = int(word,2)
. result += chr(number)
.
>>> print(result)
+↓§
Как перевести строку в двоичный код в Python 3?
Как перевести строку в двоичный код в Python 3 и вообще возможно ли это сделать со строками?
Лучший ответ
Google >>> python convert string to binary
Остальные ответы
Похожие вопросы
Ваш браузер устарел
Мы постоянно добавляем новый функционал в основной интерфейс проекта. К сожалению, старые браузеры не в состоянии качественно работать с современными программными продуктами. Для корректной работы используйте последние версии браузеров Chrome, Mozilla Firefox, Opera, Microsoft Edge или установите браузер Atom.
Работа с Base64 строками в Python
Тема кодировки является одной из самых сложных тем для понимания, особенно для новичков. В данной статье я постараюсь разобрать алгоритм работы Base64 и показать примеры использования. От вас требуется немного терпения и усидчивости. Приятного чтения!
Контекст проблемы
Вы когда-нибудь получали письмо по e-mail, содержащее PDF или изображение, при попытке открыть которое на экране выводились странные символы? Это могло произойти, если ваш e-mail сервер настроен на обработку только текстовых данных. Файлы с двоичными данными, байты (bytes) которых представляют НЕ-текстовую (non-text) информацию (например картинки), могут быть легко повреждены, если их передавать и обрабатывать в только текстовых (text-only) системах.
Типичный пример «битой» кодировки
Кодировка Base64 позволяет переводить (конвертировать) байты, содержащие двоичную или символьную (текстовую) информацию в ASCII-символы. Подробно с ASCII ознакомиться можно самостоятельно, но идея там простая: каждому литералу ставится в соответствие целое число. Т.к. диапазон значений ограничен латинскими символами + спец символы/управляющие (перевод каретки, табуляция и тд), то все можно ограничить 8 битами == 1 байтом. Т.е. ASCII — такая же кодировка, что и Base64.
P.S. Точнее, ограничить можно и 7 битами, просто добавляют 0 в старший разряд, чтобы добить до 1 байта.
Ниже мы посмотрим как работает кодирование/декодирование в Base64. Будем использовать стандартную библиотеку Python, так что проблем с повторением кода у вас возникнуть не должно. Погнали!
Что такое кодирование Base64
Кодирование / шифрование — процесс, когда в соответствие исходному литералу ставится новое уникальное значение. Обычно это число, причем в любой системе исчисления (СИ).
Кодирование в Base64 — перевод байт в ASCII-символы по определенному правилу. В информатике, основание СИ показывает, как много различных (уникальных) символов могут быть представлены числами. Как видно из имени кодировки — таких значений 64.
Картинка — такой же набор байтов, которые можно закодировать во что угодно!
Кодировка Base64 содержит:
- 26 ЗАГЛАВНЫХ символа
- 26 строчных символа
- 10 цифр
- «+» и «/» для новых строк (реализации могут отличаться)
ASCII-символы в Python можно посмотреть
$ python -V Python 3.9.7 >>> from string import ascii_lowercase >>> len(ascii_lowercase) 26 >>> ascii_lowercase ‘abcdefghijklmnopqrstuvwxyz’ >>> from string import ascii_uppercase
Каждый ASCII-символ может быть придставлен целым числом
⚠ Base64 не является алгоритмом шифрования и не должен использоваться в security целях.
Как это работает
- Получаем ASCII значение для каждого символа в кодируемой строке.
- Вычисляем 8-битный двоичный эквивалент для этих значений.
- Переводим 8-битные куски (chunks) в 6-битные просто перегруппировывая цифры.
- Переводим 6-битные двоичные группы в десятеричную форму.
- Используя Base64 таблицу кодировки, ставим в соответствие каждому числу соотв символ.
Посмотрим, как это выглядит в коде.
>>> ord(‘P’) 80 >>> bin(80) ‘0b1010000’
>>> dec_chars_eq = [ord(ch) for ch in ‘Python’] [80, 121, 116, 104, 111, 110] >>> bin_dec_range = [bin(x) for x in dec_chars_eq] [‘0b1010000’, ‘0b1111001’, ‘0b1110100’, ‘0b1101000’, ‘0b1101111’, ‘0b1101110’]
010100 000111 100101 110100 011010 000110 111101 101110
Полученные значения опять добиваем до 8 бит (в старшие разряды добавляем 0). Проверить можно так
>>> assert int(0b010100) == int(0b00010100)
После того, как привели значения к 1 байту, обратно возвращаем в десятичную форму записи
0b010100 == 0b00010100 >>> int(0b00010100) 20 >>> from_6bit_to_8bit = [int(x) for x in (0b010100, 0b000111, 0b100101, 0b110100, 0b011010, 0b000110, 0b111101, 0b101110)] [20, 7, 37, 52, 26, 6, 61, 46]
Исходя из таблицы, числу 20 соответствует символ «U«, 7 ➟ «H» и тд
В результате слово «Python» в кодировке Base64 преобразуется в «UHl0aG9u«
Для чего используется Base64 кодирование?
В компьютерах все данные различных типов представлены 0 и 1. Кроме того, некоторые каналы коммуникаций и приложений не в состоянии понять все принимаемые биты. Это потому, что последовательность 0 и 1 зависит от типа информации, которую они отражают. К примеру, 10110001 должно быть обработано по-разному, в зависимости от того, представляет ли это письмо или картинку.
Чтобы обойти это ограничение, мы можем зашифровать данные в текст, улучшив т.о. возможность корректно передать и обработать данные.
Base64 — популярный метод конвертации двоичных данных в ASCII символы, широко применяемый в большинстве сетевых протоколов и приложений.
В реальном коде, места где применяется Base64:
- почтовые серверы
- html-теги
- файлы конфигураций
- хранение ssh-ключей, подписи запросов
Кусок HTML Кусок settings.toml [secrets] SSH_PUBLIC_KEY = «LS0tLS1CRUdJTiZOAUlsQVUJMSUMgS0VZ. «
Выяснив, что иногда данные необходимо отправлять в виде текста, чтобы они не были повреждены, посмотрим как в Python обстоят дела с Base64.
Кодирование строк в Python
В Python3 доступен модуль base64 данные, который содержит необходимый функционал.
from base64 import b64encode message = «Hello world» message_bytes = message.encode(‘ascii’) base64_bytes = b64encode(message_bytes) base64_message = base64_bytes.decode(‘ascii’) print(base64_message) Output: SGVsbG8gd29ybGQ=
⚠ Важно! При обратном декодировании необходимо использовать такую же кодировку, с помощью которой исходная строка была закодирована.
Декодирование строк
Декодирование строки Base64 по сути является обратным процессом кодирования. Мы декодируем строку Base64 в байты некодированных данных. Затем мы преобразуем байтоподобный объект в строку.
from base64 import b64decode base64_message = ‘SGVsbG8gd29ybGQ=’ base64_bytes = base64_message.encode(‘ascii’) message_bytes = b64decode(base64_bytes) message = message_bytes.decode(‘ascii’) print(message) Output: Hello world
Кодирование двоичных данных
Теперь попробуем представить бинарный файл (картинку) в виде Base64 строки.
import base64 with open(‘picture.jpeg’, ‘rb’) as binary_file: binary_file_data = binary_file.read() base64_encoded_data = base64.b64encode(binary_file_data) base64_message = base64_encoded_data.decode(‘utf-8’) print(base64_message)
⚠ Важно! Открывать файл необходимо именно в режиме binary — ‘rb‘
Восстановление исходного двоичного файла
import base64 base64_img = «»» /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7 /2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAFeAV4DASIAAhEBAxEB. «»» base64_img_bytes = base64_img.encode(‘utf-8’) with open(‘decoded_image.jpeg’, ‘wb’) as file_to_save: decoded_image_data = base64.decodebytes(base64_img_bytes) file_to_save.write(decoded_image_data)
Заключение
Кодировка Base64 — это популярный метод преобразования данных в различных двоичных форматах в строку символов ASCII. Это полезно при передаче данных через сеть или приложение, которые не могут обрабатывать необработанные двоичные данные, но легко обрабатывают текст.
С помощью Python мы можем использовать модуль base64 для кодирования и декодирования текстовых и двоичных данных Base64.
Подписывайтесь на мою телегу. Больше кода — меньше багов !