2011-12-21 1 views
8

Sto cercando di trovare la posizione della prima intestazione del file Central Directory in un file Zip.Come trovare la posizione della directory centrale in un file zip?

sto leggendo questi: http://en.wikipedia.org/wiki/Zip_(file_format) http://www.pkware.com/documents/casestudies/APPNOTE.TXT

come la vedo io, posso solo eseguire la scansione attraverso i dati Zip, identificare per l'intestazione che tipo di sezione sono a, e poi fare che fino Ho colpito l'intestazione della directory centrale. Ovviamente leggo le Intestazioni File prima e uso la "dimensione compressa" per saltare i dati effettivi, e non for-loop attraverso ogni byte nel file ...

Se faccio così, allora praticamente conosco già tutti i file e le cartelle all'interno del file Zip, nel qual caso non vedo più molto l'uso della Directory Centrale.

A mio avviso, lo scopo della directory centrale è elencare i metadati del file e la posizione dei dati effettivi nel file zip in modo da non dover eseguire la scansione dell'intero file?

Dopo aver letto su fine della registrazione directory centrale, Wikipedia dice:

Questo ordinamento consente un file zip da creare in un solo passaggio, ma è solito decompresso dalla prima lettura la directory centrale al fine.

Come trovo la registrazione di Fine directory centrale facilmente? Abbiamo bisogno di ricordare che può avere un commento di dimensione arbitraria lì, quindi potrei non sapere quanti byte dalla fine del flusso di dati si trova a. Lo scannerò?

P.S. Sto scrivendo un lettore di file zip.

+0

Impossibile avviare la scansione indietro dalla fine (la directory ZIP si trova alla fine del file)? –

+1

Sì, sì, ma è davvero questo il modo in cui dovresti farlo?Scansionare all'indietro per trovare la fine della directory centrale è una possibilità, ma considerando il fatto che ha un campo di commento di dimensioni variabili di 16 bit, è possibile avere circa 65k di commenti che è necessario leggere/analizzare, e se il commento contiene il numero magico in cui la scansione fallirà. I commenti di – Tower

+0

sono sempre vuoti e cosa 64K è oggi? –

risposta

1

Ho terminato il ciclo dei byte a partire dalla fine. Il ciclo si interrompe se trova una sequenza di byte corrispondente, l'indice è sotto zero o se ha già attraversato 64k byte.

+0

Hai trovato la soluzione? Come appare la Directory centrale? Ho un file con codifica Base64. –

8

Iniziare alla fine e scansionare verso l'inizio, cercando la fine della firma della directory e contando il numero di byte che si è scansionato. Quando trovi un candidato, ottieni l'offset di byte 20 per la lunghezza del commento (L). Controlla se L + 20 corrisponde al tuo conteggio attuale. Quindi verificare che l'inizio della directory centrale (indicata dall'offset del byte 12) abbia una firma appropriata.

Se si presupponeva che i bit fossero piuttosto casuali quando il controllo della firma era un tentativo di indovinare (ad esempio, un tentativo di atterraggio in un segmento di dati), la probabilità di ottenere tutti i bit della firma corretti è piuttosto bassa. Potresti affinare questo e capire la possibilità di atterrare in un segmento di dati e la possibilità di colpire un'intestazione legittima (in funzione del numero di tali intestazioni), ma questo mi è già sembrato una bassa probabilità. Potresti aumentare il tuo livello di confidenza verificando la firma del primo record di file elencato, ma assicurati di gestire il caso limite di un file zip vuoto.

+1

Grazie per questa risposta Derek, lo apprezzo davvero –

+0

Va anche detto che è meglio iniziare dalla posizione 'endOfFile - 22', dato che la vera fine della firma della directory centrale non può avvenire dopo questa posizione. Per gli archivi con commenti vuoti, questo troverà la firma sulla prima iterazione. – Mark

+0

Ho controllato su endOfFile -22, se fallisce, prova endOfFile - 64k - 22 e loop fino a endOfFile -22 applicando questo controllo euristico ogni volta che vedo la firma. Codice qui per i curiosi: https://github.com/paulsapps/msgi/blob/840857346a84efc0b29ae00edb0b693b805ae4f1/Source/MgsLib/Fs.cpp#L323 – paulm

1

Basta incrociare le dita e sperare che non ci sia una voce con CRC, timestamp o datestamp come 06054B50 o qualsiasi altra sequenza di quattro byte che si trova a 06054B50.

+3

Realmente non penso che questo aggiunga qualcosa di terribilmente costruttivo a questa domanda. Sarebbe stato meglio aggiunto come solo un commento. –