Используя Python, Как я могу считать биты в байте?

У меня есть файл, где первый байт содержит закодированную информацию. В Matlab я могу считать байт поразрядно с var = fread(file, 8, 'ubit1'), и затем получите каждый бит var(1), var(2), и т.д.

Есть ли в Python какой-либо эквивалентный разрядный читатель?

33
задан Andreas -he-her- 1 December 2017 в 13:54
поделиться

4 ответа

Считайте биты из файла, сначала младшие биты.

def bits(f):
    bytes = (ord(b) for b in f.read())
    for b in bytes:
        for i in xrange(8):
            yield (b >> i) & 1

for b in bits(open('binary-file.bin', 'r')):
    print b
26
ответ дан 27 November 2019 в 17:52
поделиться

Наименьшей единицей, с которой вы сможете работать, является байт. Для работы на битовом уровне необходимо использовать побитовые операторы .

x = 3
#Check if the 1st bit is set:
x&1 != 0
#Returns True

#Check if the 2nd bit is set:
x&2 != 0
#Returns True

#Check if the 3rd bit is set:
x&4 != 0
#Returns False
20
ответ дан 27 November 2019 в 17:52
поделиться

Вы не сможете читать каждый бит один за другим - вы должны читать его побайтно. Однако вы можете легко извлечь биты:

f = open("myfile", 'rb')
# read one byte
byte = f.read(1)
# convert the byte to an integer representation
byte = ord(byte)
# now convert to string of 1s and 0s
byte = bin(byte)[2:].rjust(8, '0')
# now byte contains a string with 0s and 1s
for bit in byte:
    print bit
10
ответ дан 27 November 2019 в 17:52
поделиться

Есть два возможных способа вернуть i-й бит байта. «Первый бит» может относиться к старшему разряду или он может относиться к младшему разряду.

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

def bit_from_string(string, index):
       i, j = divmod(index, 8)

       # Uncomment this if you want the high-order bit first
       # j = 8 - j

       if ord(string[i]) & (1 << j):
              return 1
       else:
              return 0

Индексирование начинается с 0. Если вы хотите, чтобы индексирование начиналось с 1, вы можете настроить индекс в функции перед вызовом divmod .

Пример использования:

>>> for i in range(8):
>>>       print i, bit_from_string('\x04', i)
0 0
1 0
2 1
3 0
4 0
5 0
6 0
7 0

Теперь о том, как это работает:

Строка состоит из 8-битных байтов, поэтому сначала мы используем divmod (), чтобы разбить индекс на части:

  • i : индекс правильного байта в строке
  • j : индекс правильного бита в этом байте

Мы используем функцию ord () для преобразования символа в строка [i] в целочисленный тип. Затем (1 << j) вычисляет значение j-го бита путем сдвига 1 влево на j . Наконец, мы используем побитовое и, чтобы проверить, установлен ли этот бит. Если да, верните 1, иначе верните 0.

2
ответ дан 27 November 2019 в 17:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: