Подтвердить что ты не робот

Преобразование байтов в биты в python

Я работаю с Python3.2. Мне нужно взять шестнадцатеричный поток в качестве ввода и проанализировать его на уровне бит. Поэтому я использовал

bytes.fromhex(input_str)

чтобы преобразовать строку в фактические байты. Теперь как преобразовать эти байты в биты?

4b9b3361

Ответ 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))