#python #алгоритм #python_3x #encoding #byte
Мне нужно преобразовать строку, например "А", в строку двоичного кода, например "01100011", потом обработать немного двоичный код, пропустив его по функции "Исключающее ИЛИ" с другим двоичным кодом, например "01100011" с "11000010", тогда выйдет "10100001", и обратно перевести получившийся код в читаемую строку, например в "Т". При этом, я хочу использовать русскую, английскую и украинскую раскладку и цифры, со знаками припинания. Не подскажете, как это сделать на Python 3? Вопрос состоит в том как в Python преобразовать строку в двоичный код и обратно используя любой алгоритм кодировки?
Ответы
Ответ 1
Чтобы произвольный текст превратить в "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\nY\x1c\n\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.Ответ 2
Решение поддерживающее Unicode Basic Multilingual Plane (BMP) AKA Plane Unicode символы: s = 'отака собі тестова - String !' def encode(s): return list(map(lambda x: "{0:b}".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 !'
Комментариев нет:
Отправить комментарий