Python, how to decode Binary coded decimal (BCD)

后端 未结 2 1174
醉话见心
醉话见心 2021-01-02 04:40

Description of the binary field is:

Caller number, expressed with compressed BCD code, and the surplus bits are filled with “0xF”

相关标签:
2条回答
  • 2021-01-02 04:54

    Python 3.x has this built-in for bytes objects.

    >>> c = b'3\x00\x02\x05\x15\x13GO\xff\xff\xff\xff\xff\xff\xff\xff'
    >>> c.hex()
    '330002051513474fffffffffffffffff'
    

    And back:

    >>> c = "9F1A020840"
    >>> bytes.fromhex(c)
    b'\x9f\x1a\x02\x08@'
    
    0 讨论(0)
  • 2021-01-02 05:03

    BCD codes work with 4 bits per number, and normally encode only the digits 0 - 9. So each byte in your sequence contains 2 numbers, 1 per 4 bits of information.

    The following method uses a generator to produce those digits; I am assuming that a 0xF value means there are no more digits to follow:

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

    Here I use a right-shift operator to move the left-most 4 bits to the right, and a bitwise AND to select just the right-most 4 bits.

    Demonstration:

    >>> 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]
    

    The method works with the c output; you can skip the ord call in the method if you pass integers directly (but use the B unsigned variant instead). Alternatively, you could just read those 16 bytes straight from your file and apply this function to those bytes directly without using struct.

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