使用Python如何读取字节中的位?

时间:2010-04-05 02:57:28

标签: python byte bits

我有一个文件,其中第一个字节包含编码信息。在Matlab中,我可以用var = fread(file, 8, 'ubit1')逐位读取字节,然后按var(1), var(2)等检索每个位。

python中是否有相应的位读取器?

9 个答案:

答案 0 :(得分:25)

首先读取文件中的位,低位。

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

答案 1 :(得分:19)

您可以使用的最小单位是一个字节。要在位级别工作,您需要使用bitwise operators

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

答案 2 :(得分:10)

您将无法逐个读取每个位 - 您必须逐字节读取它。但是,您可以轻松地提取出来:

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

答案 3 :(得分:9)

使用numpy很简单:

Bytes = numpy.fromfile(filename, dtype = "uint8")
Bits = numpy.unpackbits(Bytes)

此处有更多信息:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.fromfile.html

答案 4 :(得分:5)

从文件中读取字节:bytestring = open(filename, 'rb').read(1)。注意:文件以二进制模式打开。

要获取位,将bytestring转换为整数:byte = bytestring[0](Python 3)或byte = ord(bytestring[0])(Python 2)并提取所需的位:(byte >> i) & 1

>>> for i in range(8): (b'a'[0] >> i) & 1
... 
1
0
0
0
0
1
1
0
>>> bin(b'a'[0])
'0b1100001'

答案 5 :(得分:2)

有两种方法可以返回一个字节的第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()函数将string[i]处的字符转换为整数类型。然后,(1 << j)通过左移{1} j来计算第j位的值。最后,我们使用bitwise-并测试该位是否已设置。如果是,则返回1,否则返回0。

答案 6 :(得分:2)

加入我之前使用的一些答案:

[int(i) for i in "{0:08b}".format(byte)]

从文件中读取的每个字节。 0x88字节示例的结果是:

>>> [int(i) for i in "{0:08b}".format(0x88)]
[1, 0, 0, 0, 1, 0, 0, 0]

您可以将其分配给变量,并按照初始请求进行操作。 “{0.08}”用于保证完整的字节长度

答案 7 :(得分:0)

我想这很快:

import itertools
data = range(10)
format = "{:0>8b}".format
newdata = (False if n == '0' else True for n in itertools.chain.from_iterable(map(format, data)))
print(newdata) # prints tons of True and False

答案 8 :(得分:0)

假设您有一个名为bloom_filter.bin的文件,其中包含一个位数组,您希望读取整个文件并在数组中使用这些位。

首先创建一个数组,读取后将存储这些位,

from bitarray import bitarray
a=bitarray(size)           #same as the number of bits in the file

打开文件, 使用open或with,任何东西都很好......我在这里坚持打开,

f=open('bloom_filter.bin','rb')

现在将所有位加载到数组中&#39; a&#39;一次性使用,

f.readinto(a)

&#39;一个&#39;现在是一个包含所有位的比特阵列