How to extract a value from specific bits from a byte array in Python 3?

I have a byte array that is 6 bytes in length (48 bits). Only the first six bits of each byte are relevant. The high two bits do not contain data, so they should be ignored. They should not be included when converting to a number.

I want to extract a specific range of bits from the byte array and convert it to a number, while ignoring the high two bits of each byte.

Take the following byte array as an example: b’x12x08x1cx30x32x21′
Bit 47 -> 00010010 00001000 00011100 00110000 00110010 00100001 <- Bit 0

If I want the value for bits 0 through 15. The answer should be 3233(1+32+128+1024+2048)

00010010 00001000 00011100 00110000 00110010 00100001  
                               ^^^^ XX^^^^^^ XX^^^^^^  


If I want the value for bits 6 through 12. it should be 50 (2+16+32)

00010010 00001000 00011100 00110000 00110010 00100001
                                  ^ XX^^^^^^ XX      

I can do this awkwardly in my head, but I’m having issues getting it down in Python. These are the steps that I think I should be doing, but I’m not sure if it’s the best/easiest way nor how I should be doing it…

  1. Convert my byte array into a single string containing it’s binary value
  2. Change every seventh and eighth character of the binary string (counting from the right side) to another character (“-” for example).
  3. Remove any of the “-” characters from the new string. [edited]
  4. Extract the bits that I want from the binary string. [edited]
  5. Convert that string from a binary to a value.


1 . How do I take my byte array and convert to a 48 bit binary string?
2 . Is there an easy way to change every seventh and eighth bit to “-” in my binary string?
5 . Convert a string containing a binary value to a number?

…and is my thought process any good on this, or is there an easier way to accomplish this?

I really appreciate any help with this.

[edit] I think I had STEP 3 and 4 in my question in the wrong order… I want to remove the unwanted bits BEFORE I extract my binary digits. Question edited accordingly.[/edit]


This is what I’ve come up with…

def bit_value(data, first_bit, last_bit):
    """ Returns a value based on what bits are set between first_bit and last_bit of a byte array, ignoring bit 7 and 8 of each byte."""

    # Convert bytes to a binary string
    number = int.from_bytes(data, "big")
    bits = f"{number:048b}"

    # Change 7th and 8th bits to "-"
    clean_bits = ""
    for i in range(0,48):
        if i % 8 == 0 or i % 8 == 1:
            clean_bits += "-"
            clean_bits += bits[i]

    # Strip out the unwanted "-"
    clean_bits = clean_bits.replace("-","")

    # Get the bits we want
    bits_i_want = clean_bits[35-first_bit:36-last_bit]

    # Get the value of the resulting binary string
    value = int(bits_i_want, 2)

    return value