11

バイナリ フィールドの説明は次のとおりです。

発信者番号を圧縮BCDコードで表現し、余剰ビットを「0xF」で埋める

'16c'私は構造体形式で印刷しようとしましたが、次('3', '\x00', '\x02', '\x05', '\x15', '\x13', 'G', 'O', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff')のように'16b'なり(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 コードを変換する方法を教えてください。

4

2 に答える 2

18

BCD コードは数値ごとに 4 ビットで動作し、通常は 0 ~ 9 の数字のみをエンコードします。したがって、シーケンスの各バイトには、4 ビットの情報ごとに 1 つずつ、2 つの数値が含まれます。

次のメソッドは、ジェネレーターを使用してこれらの数字を生成します。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 バイトを読み取り、構造体を使用せずにこの関数をそれらのバイトに直接適用することもできます。

于 2012-07-26T12:21:09.020 に答える