将4个整数打包为ONE BYTE?

use*_*424 16 python binary struct

我有四个整数{ a,b,c,d},可以有值的范围如下:

a - {0或1}(1位)

b - {0或1}(1位)

c - {0,1,2,...,7}(3位)

d - {0,1,2,...,7}(3位)

首先,我想将它们打包成一个字节,然后可以写入二进制文件.后来,我想解开一个字节,并从中获取到窗体(元组a,b,c,d).

我知道如何在python中读取/写入二进制文件的字节.但是如何进行打包/拆包?

Sve*_*ach 31

使用shift和按位OR,然后转换为字符以获得"byte":

x = chr(a | (b << 1) | (c << 2) | (d << 5))
Run Code Online (Sandbox Code Playgroud)

要再次解压缩该字节,首先转换为整数,然后移位并使用按位AND:

i = ord(x)
a = i & 1
b = (i >> 1) & 1
c = (i >> 2) & 7
d = (i >> 5) & 7
Run Code Online (Sandbox Code Playgroud)

说明:最初,你有

0000000a
0000000b
00000ccc
00000ddd
Run Code Online (Sandbox Code Playgroud)

左转给你

0000000a
000000b0
000ccc00
ddd00000
Run Code Online (Sandbox Code Playgroud)

按位OR结果

dddcccba
Run Code Online (Sandbox Code Playgroud)

转换为字符会将其转换为单个字节.

拆包:四个不同的右移导致

dddcccba
0dddcccb
00dddccc
00000ddd
Run Code Online (Sandbox Code Playgroud)

使用1(0b00000001)或7(0b00000111)屏蔽(按位AND )会导致

0000000a
0000000b
00000ccc
00000ddd
Run Code Online (Sandbox Code Playgroud)

再次.

  • 请注意,字符串只是Python 2中的字节串; 在Python 3中它们是Unicode,所以`chr(x)`实际上会给你一个2或4字节的字.你需要构造一个实际的`bytes`对象而不是字符串.我不确定`ch``的`bytes`等价物是什么,如果有的话. (2认同)
  • (我认为正确的做法通常是sjr做的:简单地将其作为int返回,并在实际使用它时将其更改为单个字节.) (2认同)

sjr*_*sjr 10

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
Run Code Online (Sandbox Code Playgroud)


Sco*_*ths 5

如果你需要这么多东西,那么位移会变得乏味且容易出错.有第三方库可以提供帮助 - 我写了一个名为bitstring的文章:

打包并转换为字节:

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

并打开包装:

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

这可能对你的例子来说太过分了,但是当事情变得更复杂时它会很有用.