Python - 将二进制解码为布尔值

时间:2014-06-04 13:08:28

标签: python struct binary boolean unpack

我正在尝试使用套接字接收一些数据,然后解压缩数据以进行处理。

在输入中,我有一个二进制字符串: “MsgID - 发件人 - 大小 - 时间1 - 时间2 - Resrv - bool1 - bool2”

以下是格式: “H - H - L - f - I - L - 'bool' - 'bool'”

当我收到数据时,我必须用这一行解压缩它:

messageEnaKill = struct.unpack('!HHLfIL??', messageEnaKill_raw)

然后我必须处理布尔值(最后2个)。 事实是我不知道布尔值的格式,它是char('c')还是什么?

我的第二个问题是我必须检查二进制布尔值,如果它是True或False。我怎样才能做到这一点 ? 这段代码是真的:

if msg[0] == bin(True):

考虑“msg [0]”来自“unpack”的布尔数据。

感谢您的支持!

2 个答案:

答案 0 :(得分:2)

来自struct documentation

  

'?'转换代码对应于C99定义的_Bool类型。如果此类型不可用,则使用char进行模拟。在标准模式下,它始终用一个字节表示。

?类型将作为bool类型解压缩:

>>> type(struct.unpack('?','c')[0])
<type 'bool'>

除空字符('\0')以外的任何值都将为True。所以你可以按照Jan Vlcinsky的建议。您的解决方案取决于您收到的数据。如果空字节表示False而其他字节为True,则可以继续使用?解包作为最简单的解决方案。

因此要检查消息中的第一个布尔值是否为true,请使用此测试:

messageEnaKill = struct.unpack('!HHLfIL??', messageEnaKill_raw)
if(messageEnaKill[7]==True):
    # do something

答案 1 :(得分:1)

您可以决定将多个位放入一个整数并打包/解包该整数

要转换布尔值列表,以下功能可能会有所帮助:

def encode_booleans(bool_lst):
    res = 0
    for i, bval in enumerate(bool_lst):
        res += int(bval) << i
    return res

def decode_booleans(intval, bits):
    res = []
    for bit in xrange(bits):
        mask = 1 << bit
        res.append((intval & mask) == mask)
    return res

测试它:

>>> blst = [True, False, True]
>>> encode_booleans(blst)
5
>>> decode_booleans(5, 3)
[True, False, True]
>>> decode_booleans(5, 10)
[True, False, True, False, False, False, False, False, False, False]

编码

然后分两步完成编码

  1. 将一组布尔变成一个整数
  2. 使用所有其他类型以及新创建的整数
  3. pack创建结果结构

    解码

    解码也分两步进行,只是按照相反的顺序

    1. 解包到预期结构中,布尔值表示为单个整数
    2. 将整数解码为一组布尔值
    3. 这假设您已对编码部分进行控制。

      完整示例

      假设import struct完成并且定义了上述两个函数:

      >>> packform = "!HHLfILB"
      >>> msg_id = 101
      >>> sender = 22
      >>> size = 1000
      >>> time1 = 123.45
      >>> time2 = 222
      >>> bool1 = True
      >>> bool2 = False
      >>> bools_enc = encode_booleans([bool1, bool2])
      >>> bools_enc
      1
      >>> resrv = 55
      >>> msg_lst = [msg_id, sender, size, time1, time2, resrv, bools_enc]
      >>> enc = struct.pack(packform, *msg_lst)
      >>> enc
      '\x00e\x00\x16\x00\x00\x03\xe8B\xf6\xe6f\x00\x00\x00\xde\x00\x00\x007\x01'
      >>> decoded = struct.unpack(packform, enc)
      >>> decoded
      (101, 22, 1000, 123.44999694824219, 222, 55, 1)
      >>> msg_lst
      [101, 22, 1000, 123.45, 222, 55, 1]
      >>> new_msg_id, new_sender, new_size, new_time1, new_time2, new_resrv, new_bools_enc = decoded
      >>> new_bool1, new_bool2 = decode_booleans(new_bools_enc, 2)
      >>> new_bool1
      True
      >>> new_bool2
      False