Вопрос-Ответ

Convert binary to ASCII and vice versa

Преобразование двоичного файла в ASCII и наоборот

Использование этого кода для получения строки и преобразования ее в двоичный файл:

bin(reduce(lambda x, y: 256*x+y, (ord(c) for c in 'hello'), 0))

это выводит:

0b110100001100101011011000110110001101111

Который, если я помещу его на этот сайт (на сайте справа), я получу свое сообщение hello обратно. Мне интересно, какой метод он использует. Я знаю, что мог бы разделить строку двоичного файла на 8, а затем сопоставить ее с соответствующим значением to bin(ord(character)) или каким-либо другим способом. Действительно ищу что-нибудь попроще.

Переведено автоматически
Ответ 1

Для символов ASCII в диапазоне [ -~] на Python 2:

>>> import binascii
>>> bin(int(binascii.hexlify('hello'), 16))
'0b110100001100101011011000110110001101111'

Наоборот:

>>> n = int('0b110100001100101011011000110110001101111', 2)
>>> binascii.unhexlify('%x' % n)
'hello'

В Python 3.2+:

>>> bin(int.from_bytes('hello'.encode(), 'big'))
'0b110100001100101011011000110110001101111'

Наоборот:

>>> n = int('0b110100001100101011011000110110001101111', 2)
>>> n.to_bytes((n.bit_length() + 7) // 8, 'big').decode()
'hello'

Для поддержки всех символов Unicode в Python 3:

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'

Вот версия, совместимая с Python 2/3 с одним исходным кодом:

import binascii

def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
bits = bin(int(binascii.hexlify(text.encode(encoding, errors)), 16))[2:]
return bits.zfill(8 * ((len(bits) + 7) // 8))

def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
n = int(bits, 2)
return int2bytes(n).decode(encoding, errors)

def int2bytes(i):
hex_string = '%x' % i
n = len(hex_string)
return binascii.unhexlify(hex_string.zfill(n + (n & 1)))

Пример

>>> text_to_bits('hello')
'0110100001100101011011000110110001101111'
>>> text_from_bits('110100001100101011011000110110001101111') == u'hello'
True
Ответ 2

Тольковстроенный python

Вот чистый метод python для простых строк, оставленный здесь для потомков.

def string2bits(s=''):
return [bin(ord(x))[2:].zfill(8) for x in s]

def bits2string(b=None):
return ''.join([chr(int(x, 2)) for x in b])

s = 'Hello, World!'
b = string2bits(s)
s2 = bits2string(b)

print 'String:'
print s

print '\nList of Bits:'
for x in b:
print x

print '\nString:'
print s2

String:
Hello, World!

List of Bits:
01001000
01100101
01101100
01101100
01101111
00101100
00100000
01010111
01101111
01110010
01101100
01100100
00100001

String:
Hello, World!
Ответ 3

Я не уверен, как, по-вашему, вы можете это сделать, кроме как посимвольно - по сути, это посимвольная операция. Безусловно, существует код, который сделает это за вас, но нет "более простого" способа, чем выполнять это посимвольно.

Во-первых, вам нужно убрать префикс 0b и дополнить строку нулем слева, чтобы ее длина была кратна 8, чтобы упростить разделение битовой строки на символы:

bitstring = bitstring[2:]
bitstring = -len(bitstring) % 8 * '0' + bitstring

Затем вы разделяете строку на блоки по восемь двоичных цифр, преобразуете их в символы ASCII и соединяете их обратно в строку:

string_blocks = (bitstring[i:i+8] for i in range(0, len(bitstring), 8))
string = ''.join(chr(int(char, 2)) for char in string_blocks)

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

Ответ 4

Это мой способ решить вашу задачу:

str = "0b110100001100101011011000110110001101111"
str = "0" + str[2:]
message = ""
while str != "":
i = chr(int(str[:8], 2))
message = message + i
str = str[8:]
print message
python