2012-07-26 24 views
6

Descripción del campo binario es:Python, cómo decodificar decimal codificado en binario (BCD)

número de llamadas, expresada con código BCD comprimido, y los bits sobrantes se rellenan con “0xF”

He intentado imprimir con el formato struct '16c' y obtengo: ('3', '\x00', '\x02', '\x05', '\x15', '\x13', 'G', 'O', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff') y si uso '16b' obtengo (51, 0, 2, 5, 21, 19, 71, 79, -1, -1, -1, -1, -1, -1, -1, -1). Y no es correcto, debería obtener el número de teléfono, y los números anteriores no son válidos.

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

Arriba está el código que no funciona y obtengo números inválidos. ¿Con qué formato debería desempaquetar ese campo de 16 bytes y cómo convertir el código BCD?

Respuesta

11

Los códigos BCD funcionan con 4 bits por número y normalmente codifican solo los dígitos 0 - 9. De modo que cada byte en su secuencia contiene 2 números, 1 por cada 4 bits de información.

El siguiente método usa un generador para producir esos dígitos; Estoy asumiendo que un valor 0xF significa que no hay más dígitos a seguir:

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

Aquí, he utilizado un right-shift operator para mover más a la izquierda 4 bits a la derecha, y una bitwise AND para seleccionar sólo la más a la derecha 4 bits

Demostración:

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

El método funciona con la salida c; puede omitir la llamada ord en el método si pasa enteros directamente (pero en su lugar use la variante sin signo B). Alternativamente, puede leer esos 16 bytes directamente desde su archivo y aplicar esta función a esos bytes directamente sin usar struct.

+0

Muchas gracias. – Whit3H0rse

+0

+1 ¡Muy elegante y pitónico! – Kos

Cuestiones relacionadas