Using Python How can I read the bits in a byte?

前端 未结 9 510
礼貌的吻别
礼貌的吻别 2020-12-05 06:55

I have a file where the first byte contains encoded information. In Matlab I can read the byte bit by bit with var = fread(file, 8, \'ubit1\'), and then retrie

相关标签:
9条回答
  • 2020-12-05 07:01

    There are two possible ways to return the i-th bit of a byte. The "first bit" could refer to the high-order bit or it could refer to the lower order bit.

    Here is a function that takes a string and index as parameters and returns the value of the bit at that location. As written, it treats the low-order bit as the first bit. If you want the high order bit first, just uncomment the indicated line.

    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
    

    The indexing starts at 0. If you want the indexing to start at 1, you can adjust index in the function before calling divmod.

    Example usage:

    >>> 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
    

    Now, for how it works:

    A string is composed of 8-bit bytes, so first we use divmod() to break the index into to parts:

    • i: the index of the correct byte within the string
    • j: the index of the correct bit within that byte

    We use the ord() function to convert the character at string[i] into an integer type. Then, (1 << j) computes the value of the j-th bit by left-shifting 1 by j. Finally, we use bitwise-and to test if that bit is set. If so return 1, otherwise return 0.

    0 讨论(0)
  • 2020-12-05 07:02

    The smallest unit you'll be able to work with is a byte. To work at the bit level you need to use 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
    
    0 讨论(0)
  • 2020-12-05 07:07

    To read a byte from a file: bytestring = open(filename, 'rb').read(1). Note: the file is opened in the binary mode.

    To get bits, convert the bytestring into an integer: byte = bytestring[0] (Python 3) or byte = ord(bytestring[0]) (Python 2) and extract the desired bit: (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'
    
    0 讨论(0)
  • 2020-12-05 07:08

    Joining some of the previous answers I would use:

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

    For each byte read from the file. The results for an 0x88 byte example is:

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

    You can assign it to a variable and work as per your initial request. The "{0.08}" is to guarantee the full byte length

    0 讨论(0)
  • 2020-12-05 07:09

    This is pretty fast I would think:

    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
    
    0 讨论(0)
  • 2020-12-05 07:13

    You won't be able to read each bit one by one - you have to read it byte by byte. You can easily extract the bits out, though:

    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
    
    0 讨论(0)
提交回复
热议问题