Python,如何解码二进制编码的十进制(BCD)

新手上路,请多包涵

二进制字段的描述是:

来电号码,用压缩BCD码表示,多余位用“0xF”填充

I have tried to print with struct format '16c' and I get: ('3', '\x00', '\x02', '\x05', '\x15', '\x13', 'G', 'O', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff') and if I use '16b' i get (51, 0, 2, 5, 21, 19, 71, 79, -1, -1, -1, -1, -1, -1, -1, -1) .它不正确,我应该得到电话号码,上面的号码无效。

 print struct.unpack_from('>16b', str(data.read()),offset=46)

以上是无效的代码,我得到了无效的数字。我应该用什么格式解压那个 16 字节字段以及如何转换 BCD 码?

原文由 Whit3H0rse 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 606
2 个回答

BCD 代码每个数字使用 4 位,通常只对数字 0 - 9 进行编码。因此序列中的每个字节包含 2 个数字,每 4 位信息 1 个。

以下方法使用生成器生成这些数字;我假设 0xF 值意味着后面没有更多数字:

 def bcdDigits(chars):
    for char in chars:
        char = ord(char)
        for val in (char >> 4, char & 0xF):
            if val == 0xF:
                return
            yield val

在这里,我使用 右移运算符 将最左边的 4 位向右移动,并使用 按位 AND 仅选择最右边的 4 位。

示范:

 >>> characters = ('3', '\x00', '\x02', '\x05', '\x15', '\x13', 'G', 'O', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff')
>>> list(bcdDigits(characters))
[3, 3, 0, 0, 0, 2, 0, 5, 1, 5, 1, 3, 4, 7, 4]

该方法适用于 c 输出;如果您直接传递整数,则可以跳过方法中的 ord 调用(但改用 B 无符号变体)。或者,您可以直接从文件中读取这 16 个字节,并将此函数直接应用于这些字节,而无需使用 struct。

原文由 Martijn Pieters 发布,翻译遵循 CC BY-SA 3.0 许可协议

来自我的项目的功能。第二个参数放置小数点。

 def bcd_decode(data: bytes, decimals: int):
    '''
    Decode BCD number
    '''
    res = 0
    for n, b in enumerate(reversed(data)):
        res += (b & 0x0F) * 10 ** (n * 2 - decimals)
        res += (b >> 4) * 10 ** (n * 2 + 1 - decimals)
    return res

原文由 dIcEmAN 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题