2012-07-26 4 views
6

Beschreibung des Binärfeld zu dekodieren ist:Python, wie binärcodierte Dezimalzahl (BCD)

Anrufernummer, mit Druck BCD-Code ausgedrückt wird, und die überzähligen Bits werden gefüllt mit „0 × F“

Ich habe versucht, mit Strukturformat '16c' zu drucken, und ich bekomme: ('3', '\x00', '\x02', '\x05', '\x15', '\x13', 'G', 'O', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff') und wenn ich '16b' verwende, bekomme ich (51, 0, 2, 5, 21, 19, 71, 79, -1, -1, -1, -1, -1, -1, -1, -1). Und es ist nicht korrekt, ich sollte die Telefonnummer bekommen, und die obigen Nummern sind ungültig.

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

Oben ist Code, der nicht funktioniert hat, und ich bekomme ungültige Zahlen. Mit welchem ​​Format soll ich das 16-Byte-Feld entpacken und BCD-Code konvertieren?

Antwort

11

BCD-Codes arbeiten mit 4 Bits pro Nummer und kodieren normalerweise nur die Ziffern 0 - 9. Jedes Byte in Ihrer Sequenz enthält also 2 Zahlen, 1 pro 4 Bits Information.

Die folgende Methode verwendet einen Generator, um diese Ziffern zu erzeugen; Ich gehe davon aus, dass ein 0xF Wert bedeutet, dass es keine weiteren Ziffern folgen:

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

Hier verwende ich ein right-shift operator die am weitesten links stehenden 4 Bits nach rechts zu bewegen, und ein bitwise AND wählen Sie einfach dem am weitesten rechts stehenden 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] 

Das Verfahren arbeitet mit dem c Ausgang; Sie können den Aufruf ord in der Methode überspringen, wenn Sie Ganzzahlen direkt übergeben (verwenden Sie stattdessen stattdessen die nicht signierte B-Variante). Alternativ könnten Sie diese 16 Bytes direkt aus Ihrer Datei lesen und diese Funktion direkt auf diese Bytes anwenden, ohne struct zu verwenden.

+0

Vielen Dank. – Whit3H0rse

+0

+1 Sehr elegant und pythonisch! – Kos