Necesita ayuda para descomprimir los datos zlib almacenados en el código de barras azteca (Ticket de Deutsche Bahn)

Premisa

Estoy tratando de decodificar los datos del formato de código de barras utilizado actualmente en los boletos emitidos por Deutsche Bahn (ferrocarril alemán). He encontrado estositio web muy útil (alemán) que ya hace algo similar y ofrece unscript de python.

El sitio web afirma que los datos están comprimidos conzlib, el blob resultante se firma con DSA y todo se almacena en el código de barras (formato azteca).Ejemplo de dicho código de barras

Problema

He utilizado el script proporcionado en el sitio web para decodificar con éxito un ticket. Instaló la biblioteca python-pyasn1. Lea el código de barras (usadoBCTester según las instrucciones, tuve algunos problemas con la aplicación NeoReader) y convirtió el resultado a hexadecimal. Guarde los datos hexadecimales como archivos de texto sin formato (como es requerido por la secuencia de comandos) y analizó el archivo con la secuencia de comandos. Funcionó.

Pero el guión está haciendo demasiado. Me gustaría hacer el análisis por mí mismo, pero no puedo hacer que la descompresión zlib funcione y entiendo muy poco del código para darle sentido. Casi no sé Python. Sin embargo, tengo algo de experiencia en programación.

Si simplemente mira los datos del código de barras, se ve así:https://gist.github.com/oelna/096787dc18596aaa4f5f

La primera pregunta sería: ¿Cuál es la firma DSA y primero necesito dividirla de los datos comprimidos reales?

El segundo: ¿Cómo podría ser un simple script de Python que lea el blob de código de barras de un archivo y simplemente lo descomprima, para que pueda analizar más el formato? Tenía algo en mente como

#!/usr/bin python

import zlib

ticket = open('ticketdata.txt').read()

print zlib.decompress(ticket)

Pero no está funcionando. Cualquier sugerencia en la dirección correcta sería apreciada.

Aquí están los datos hexadecimales que el script puede leer si se guardan en un archivo:

23 55 54 30 31 30 30 38 30 30 30 30 30 31 30 2c 02 14 1c 3d e9 2d cd 5e c4 c0 56 bd ae 61 3e 54 ad a1 b3 26 33 d2 02 14 40 75 03 d0 cf 9c c1 f5 70 58 bd 59 50 a7 af c5 eb 0a f4 74 00 00 00 00 30 32 37 31 78 9c 65 50 cb 4e c3 30 10 e4 53 2c 71 43 4a d9 f5 2b 36 b7 84 04 52 01 55 51 40 1c 51 01 23 2a 42 0e 21 15 3f c7 8d 1f 63 36 11 52 2b 7c f1 78 76 76 66 bd f7 8f 4d 5d 54 c4 44 ce 10 05 d2 eb 78 5b ac 32 7b b4 77 c8 11 6b 62 c7 d6 79 aa ea aa 16 e1 b2 22 4d c4 01 ad 36 58 61 ca 6b 30 c6 e5 64 a0 b6 97 0f a6 a9 6f d6 71 df c7 cf 3e 7f 37 93 66 8e c6 71 de 92 4c c0 e1 22 0d fd 57 7a cb ee b6 cf ef 69 54 fd 66 44 05 31 d0 03 18 01 05 40 04 70 9c 51 46 ad 38 49 33 00 86 20 dd 42 88 04 22 5f a6 a1 db f6 78 79 d4 79 95 76 1f 3f df fd e7 98 86 16 b1 30 0b 65 d6 3c bd 2a 15 ce d8 ab e5 79 9d 47 7b da 34 13 c7 34 73 5a 6b 0b 35 72 d9 5c 0d bb ae 53 aa e8 5f 86 b4 01 e9 25 8d 0d 50 8e 72 3c 39 3c b2 13 94 82 74 ce 2d c7 b3 41 8b ed 4c 9f f5 0b e2 85 6c 01 8c fe c7 b8 e9 87 8c d9 f1 90 28 a3 73 fe 05 6d de 5f f1
Actualización / Solución:

El consejo de Mark Adler me puso en el camino correcto. Me llevó horas, pero hackeé una solución funcional para este problema en particular. Si hubiera sido más inteligente, habría reconocido el encabezado zlib78 9C en el desplazamiento 68. Simplemente divida los datos en este punto y la segunda mitad se descomprime sin queja. Ten cuidado, muy tristepython

dsa_signature = ''
zlib_data = ''
cursor = 0

with open('ticketdata.txt', "rb") as fp:
    chunk = fp.read(1)
    while chunk:
        if(cursor < 68):
            dsa_signature += chunk
        else:
            zlib_data += chunk

        chunk = fp.read(1)
        cursor = cursor + 1


print "\nSignature:"
print "%s\n" % dsa_signature
print "\nCompressed data:"
print "%s\n" % zlib_data
print "\nDecoded:"
print zlib.decompress(zlib_data)

Si hay una solución fácil para esto, siéntase libre de comentar. Continuaré trabajando en esto un poco más e intentaré que sea una solución más robusta que busque activamente el encabezado zlib, sin codificar el desplazamiento. La primera mitad es un código de identificación, como#UT010080000060,, seguido de unASN.1 Firma DSA, que afortunadamente no necesito verificar o modificar.

Respuestas a la pregunta(1)

Su respuesta a la pregunta