Мне нужно преобразовать строку, например "А", в строку двоичного кода, например "01100011", потом обработать немного двоичный код, пропустив его по функции "Исключающее ИЛИ" с другим двоичным кодом, например "01100011" с "11000010", тогда выйдет "10100001", и обратно перевести получившийся код в читаемую строку, например в "Т".
При этом, я хочу использовать русскую, английскую и украинскую раскладку и цифры, со знаками припинания. Не подскажете, как это сделать на Python 3?
Вопрос состоит в том как в Python преобразовать строку в двоичный код и обратно используя любой алгоритм кодировки?
Ответ
Чтобы произвольный текст превратить в "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р
См. Convert binary to ASCII and vice versa
Чтобы выполнить 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
Y\x1c
\x0b\x07\x01'
>>> xor(_, key).decode() # и обратно
'hello world'
См. Перевести с PHP на python: XOR с ключём для строки
Для больших строк, можно 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'
Если вы хотите ускорить эту функцию, см. Simple Python Challenge: Fastest Bitwise XOR on Data Buffers
Комментариев нет:
Отправить комментарий