Packing 4 Integers as ONE BYTE?

前端 未结 4 1269
予麋鹿
予麋鹿 2020-12-16 13:35

I have four integers {a, b, c, d} that can have the following range of values:

a - {0 or 1} (1 bi

相关标签:
4条回答
  • 2020-12-16 14:18

    If you need to this kind of thing a lot then bit shifting can become tedious and error prone. There are third-party libraries that can help - I wrote one called bitstring:

    To pack and convert to a byte:

    x = bitstring.pack('2*uint:1, 2*uint:3', a, b, c, d).bytes
    

    and to unpack:

    a, b, c, d = bitstring.BitArray(bytes=x).unpack('2*uint:1, 2*uint:3')
    

    This is probably overkill for your example, but it's helpful when things get more complicated.

    0 讨论(0)
  • 2020-12-16 14:20

    Pretty simple. Mask (for range), shift them into place, and or them together.

    packed = ((a & 1) << 7) | ((b & 1) << 6) | ((c & 7) << 3) | (d & 7)
    
    a = (packed >> 7) & 1
    b = (packed >> 6) & 1
    c = (packed >> 3) & 7
    d = packed & 7
    
    0 讨论(0)
  • 2020-12-16 14:29
    def encode(a, b, c, d):
      return a | b << 1 | c << 2 | d << 5
    
    def decode(x):
      return x & 1, (x >> 1) & 1, (x >> 2) & 7, (x >> 5) & 7
    
    0 讨论(0)
  • 2020-12-16 14:34

    Use shift and bitwise OR, then convert to a character to get a "byte":

    x = chr(a | (b << 1) | (c << 2) | (d << 5))
    

    To unpack this byte again, first convert to an integer, then shift and use bitwise AND:

    i = ord(x)
    a = i & 1
    b = (i >> 1) & 1
    c = (i >> 2) & 7
    d = (i >> 5) & 7
    

    Explanation: Initially, you have

    0000000a
    0000000b
    00000ccc
    00000ffffd
    

    The left-shifts give you

    0000000a
    000000b0
    000ccc00
    ffffd00000
    

    The bitwise OR results in

    ffffdcccba
    

    Converting to a character will convert this to a single byte.

    Unpacking: The four different right-shifts result in

    ffffdcccba
    0ffffdcccb
    00ffffdccc
    00000ffffd
    

    Masking (bitwise AND) with 1 (0b00000001) or 7 (0b00000111) results in

    0000000a
    0000000b
    00000ccc
    00000ffffd
    

    again.

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