Convert bytes to bits in python

后端 未结 9 1637
轮回少年
轮回少年 2020-11-30 07:18

I am working with Python3.2. I need to take a hex stream as an input and parse it at bit-level. So I used

bytes.fromhex(input_str)

to convert t

相关标签:
9条回答
  • 2020-11-30 07:47

    What about something like this?

    >>> bin(int('ff', base=16))
    '0b11111111'
    

    This will convert the hexadecimal string you have to an integer and that integer to a string in which each byte is set to 0/1 depending on the bit-value of the integer.

    As pointed out by a comment, if you need to get rid of the 0b prefix, you can do it this way:

    >>> bin(int('ff', base=16)).lstrip('0b')
    '11111111'
    

    or this way:

    >>> bin(int('ff', base=16))[2:]
    '11111111'
    
    0 讨论(0)
  • 2020-11-30 07:52

    The other answers here provide the bits in big-endian order ('\x01' becomes '00000001')

    In case you're interested in little-endian order of bits, which is useful in many cases, like common representations of bignums etc - here's a snippet for that:

    def bits_little_endian_from_bytes(s):
        return ''.join(bin(ord(x))[2:].rjust(8,'0')[::-1] for x in s)
    

    And for the other direction:

    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))
    
    0 讨论(0)
  • 2020-11-30 08:04

    Operations are much faster when you work at the integer level. In particular, converting to a string as suggested here is really slow.

    If you want bit 7 and 8 only, use e.g.

    val = (byte >> 6) & 3
    

    (this is: shift the byte 6 bits to the right - dropping them. Then keep only the last two bits 3 is the number with the first two bits set...)

    These can easily be translated into simple CPU operations that are super fast.

    0 讨论(0)
  • 2020-11-30 08:09

    Here how to do it using format()

    print "bin_signedDate : ", ''.join(format(x, '08b') for x in bytevector)
    

    It is important the 08b . That means it will be a maximum of 8 leading zeros be appended to complete a byte. If you don't specify this then the format will just have a variable bit length for each converted byte.

    0 讨论(0)
  • 2020-11-30 08:10

    using python format string syntax

    >>> mybyte = bytes.fromhex("0F") # create my byte using a hex string
    >>> binary_string = "{:08b}".format(int(mybyte.hex(),16))
    >>> print(binary_string)
    00001111
    

    The second line is where the magic happens. All byte objects have a .hex() function, which returns a hex string. Using this hex string, we convert it to an integer, telling the int() function that it's a base 16 string (because hex is base 16). Then we apply formatting to that integer so it displays as a binary string. The {:08b} is where the real magic happens. It is using the Format Specification Mini-Language format_spec. Specifically it's using the width and the type parts of the format_spec syntax. The 8 sets width to 8, which is how we get the nice 0000 padding, and the b sets the type to binary.

    I prefer this method over the bin() method because using a format string gives a lot more flexibility.

    0 讨论(0)
  • 2020-11-30 08:11

    Another way to do this is by using the bitstring module:

    >>> from bitstring import BitArray
    >>> input_str = '0xff'
    >>> c = BitArray(hex=input_str)
    >>> c.bin
    '0b11111111'
    

    And if you need to strip the leading 0b:

    >>> c.bin[2:]
    '11111111'
    

    The bitstring module isn't a requirement, as jcollado's answer shows, but it has lots of performant methods for turning input into bits and manipulating them. You might find this handy (or not), for example:

    >>> c.uint
    255
    >>> c.invert()
    >>> c.bin[2:]
    '00000000'
    

    etc.

    0 讨论(0)
提交回复
热议问题