У меня есть файл, где первый байт содержит закодированную информацию. В Matlab я могу считать байт поразрядно с var = fread(file, 8, 'ubit1')
, и затем получите каждый бит var(1), var(2)
, и т.д.
Есть ли в Python какой-либо эквивалентный разрядный читатель?
Считайте биты из файла, сначала младшие биты.
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
Наименьшей единицей, с которой вы сможете работать, является байт. Для работы на битовом уровне необходимо использовать побитовые операторы .
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
Вы не сможете читать каждый бит один за другим - вы должны читать его побайтно. Однако вы можете легко извлечь биты:
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
Есть два возможных способа вернуть 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.