Вы ищете это:
packed_data = ''.join(chr(int(asciiString[i:i+8], 2))
for i in range(0, len(asciiString), 8))
Он будет принимать 8 бит за раз от asciiString
, интерпретировать его как целое число и выводить соответствующий байт.
Ваша проблема здесь в том, что для правильной работы требуется, чтобы длина asciiString
была кратна 8 битам.Если нет, вы вставите нулевые биты перед последними несколькими действительными битами.
Так что вам нужно где-то хранить количество бит в последнем байте, чтобы вы знали, что игнорировать эти биты, когда получите их обратно,вместо того, чтобы интерпретировать их как нули.Вы можете попробовать:
packed_data = chr(len(asciiString) % 8) + packed_data
Затем, когда вы читаете это обратно:
packed_input = coded_file.read()
last_byte_length, packed_input, last_byte = (packed_input[0],
packed_input[1:-1],
packed_input[-1])
if not last_byte_length: last_byte_length = 8
ascii_input = ''.join(chain((bin(ord(byte))[2:].zfill(8) for byte in packed_input),
tuple(bin(ord(last_byte))[2:].zfill(last_byte_length),)))
# OR
# ascii_input = ''.join(chain(('{0:0=8b}'.format(byte) for byte in packed_input),
# tuple(('{0:0=' + str(last_byte_length) + '8b}').format(last_byte),)))
Редактировать: вам нужно либо удалить '0b' из строк, возвращаемых bin()
, либо, на2.6 или новее, желательно использовать новые, альтернативные версии, которые я добавил, которые используют форматирование строк вместо bin()
, нарезку и zfill()
.
Редактировать: Спасибо, eryksun, хорошо использовать цепочку, чтобы избежать копированиястроки ASCII.Также необходимо позвонить ord(byte)
в bin()
версии.