Преобразование байтов в биты в python
Я работаю с Python3.2. Мне нужно взять шестнадцатеричный поток в качестве ввода и проанализировать его на уровне бит. Поэтому я использовал
bytes.fromhex(input_str)
чтобы преобразовать строку в фактические байты. Теперь как преобразовать эти байты в биты?
Ответы
Ответ 1
Другой способ сделать это - использовать модуль bitstring
:
>>> from bitstring import BitArray
>>> input_str = '0xff'
>>> c = BitArray(hex=input_str)
>>> c.bin
'0b11111111'
И если вам нужно снять ведущую 0b
:
>>> c.bin[2:]
'11111111'
Модуль bitstring
не является обязательным требованием, как показывает ответ jcollado, но он имеет множество эффективных методов для ввода ввода в биты и управления ими. Вы можете найти это удобно (или нет), например:
>>> c.uint
255
>>> c.invert()
>>> c.bin[2:]
'00000000'
и др.
Ответ 2
Операции выполняются намного быстрее, когда вы работаете на целочисленном уровне. В частности, преобразование в строку, как предлагается здесь, очень медленно.
Если вы хотите использовать только бит 7 и 8, используйте, например,
val = (byte >> 6) & 3
(это: сдвиньте байты на 6 бит вправо, отбросив их, а затем сохраните только последние два бита 3
- это число с двумя установленными двумя битами...)
Они легко могут быть переведены на простые операции с процессором, которые очень быстрые.
Ответ 3
Как насчет этого?
>>> bin(int('ff', base=16))
'0b11111111'
Это преобразует шестнадцатеричную строку в целое число и целое число в строку, в которой каждый байт установлен в 0/1, в зависимости от битового значения целого числа.
Как указано в комментарии, если вам нужно избавиться от префикса 0b
, вы можете сделать это следующим образом:
>>> bin(int('ff', base=16)).lstrip('0b')
11111111
или следующим образом:
>>> bin(int('ff', base=16))[2:]
11111111
Ответ 4
В двоичный код:
bin(byte)[2:].zfill(8)
Ответ 5
Я думаю, что проще всего использовать numpy
здесь. Например, вы можете прочитать файл в виде байтов, а затем быстро разбить его на биты следующим образом:
Bytes = numpy.fromfile(filename, dtype = "uint8")
Bits = numpy.unpackbits(Bytes)
Ответ 6
Используйте ord
при чтении байтов чтения:
byte_binary = bin(ord(f.read(1))) # Add [2:] to remove the "0b" prefix
Или
Использование str.format()
:
'{:08b}'.format(ord(f.read(1)))
Ответ 7
Здесь, как это сделать, используя format()
print "bin_signedDate : ", ''.join(format(x, '08b') for x in bytevector)
Важно 08b. Это означает, что для заполнения байта будет добавлено максимум 8 ведущих нулей. Если вы не укажете это, тогда формат будет иметь переменную длину бит для каждого преобразованного байта.
Ответ 8
Другие ответы здесь содержат биты в big-endian order ('\x01'
становится '00000001'
)
В случае, если вас интересует малопорядковый порядок бит, который во многих случаях полезен, например, общие представления о бинумах и т.д.
здесь фрагмент для этого:
def bits_little_endian_from_bytes(s):
return ''.join(bin(ord(x))[2:].rjust(8,'0')[::-1] for x in s)
И для другого направления:
def bytes_from_bits_little_endian(s):
return ''.join(chr(int(s[i:i+8][::-1], 2)) for i in range(0, len(s), 8))