2009-09-03 7 views
10

Sto scrivendo un'applicazione che deve comprimere i dati compressi da un'altra applicazione (che è fuori dal mio controllo - non posso apportare modifiche al suo codice sorgente). L'applicazione produttore utilizza zlib per comprimere i dati utilizzando il meccanismo z_stream. Usa spesso Z_FULL_FLUSH (probabilmente troppo spesso, secondo me, ma è un'altra questione). Questa applicazione di terze parti è anche in grado di decomprimere i propri dati, quindi sono abbastanza fiducioso che i dati stessi siano corretti.Errore di decompressione zlib

Nella mia prova, sto usando questa app di terzi per comprimere il seguente semplice file di testo (in esadecimale):

48 65 6c 6c 6f 20 57 6f 72 6c 64 21 0d 0a

I byte compressi che ricevo dalla app simile a questa (di nuovo , in esadecimale):

78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff

Se provo e comprimere gli stessi dati, ottengo risultati molto simili:

78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55

ci sono due differenze che posso vedere:

In primo luogo, il quarto byte è F2, piuttosto che F3, in modo che lo sgonfiare "blocco finale" non è stata impostata bit. Presumo che ciò sia dovuto al fatto che l'interfaccia del flusso non sa mai quando sarà la fine dei dati in arrivo, quindi non imposta mai quel bit?

Infine, gli ultimi quattro byte nei dati esterni sono 00 00 FF FF, mentre nei dati di test è 24 E9 04 55. Ricerca in giro ho trovato su questa pagina

http://www.bolet.org/~pornin/deflate-flush.html

... che si tratta di una firma di sincronizzazione o di scarico totale.

Quando provo a decomprimere i miei dati utilizzando la funzione decompress(), tutto funziona perfettamente. Tuttavia, quando provo a decomprimere i dati esterni, la chiamata alla funzione decompress() ha esito negativo con un codice di ritorno Z_DATA_ERROR, che indica dati corrotti.

ho alcune domande:

  1. dovrei essere in grado di utilizzare la "decompressione" zlib funzione per decomprimere dati che sono stati compressi con il metodo z_stream?

  2. Nell'esempio sopra, qual è il significato degli ultimi quattro byte? Dato che sia il flusso di dati compresso esternamente che il mio flusso di dati di test hanno la stessa lunghezza, cosa rappresentano i miei ultimi quattro byte?

Acclamazioni

+0

Non ho idea di questo, ma un bit potenzialmente rilevante di informazioni che hai dimenticato di aggiungere alla tua domanda è come esattamente la decompressione di zlib fallisce. –

+0

Grazie - ha aggiunto anche questo. – Thomi

risposta

7

Grazie a zlib gli autori, ho trovato la risposta.L'applicazione di terze parti sta generando flussi di zlib che non sono finiti in modo corretto:

78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff

Questo è un flusso zlib parziale, costituito da un'intestazione zlib e da un flusso di svuotamento parziale parziale. Esistono due blocchi , nessuno dei quali è un ultimo blocco . Il secondo blocco è un blocco vuoto vuoto, utilizzato come marker quando lo svuotamento . Un decodificatore zlib dovrebbe decodificare correttamente ciò che è lì, e quindi continuare a cercare i dati dopo quei byte.

78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55

Questo è un flusso zlib completo, costituito da un'intestazione zlib, un singolo blocco contrassegnato come l'ultimo blocco e un rimorchio zlib . Il trailer è il checksum Adler-32 dei dati non compressi .

Quindi la mia decompressione ha esito negativo, probabilmente perché manca il CRC, oppure il codice di decompressione continua a cercare altri dati che non esistono.