2011-12-21 6 views
8

Próbuję znaleźć pozycję pierwszego nagłówka pliku Central Directory w pliku Zip.Jak znaleźć pozycję katalogu centralnego w pliku Zip?

Czytam te: http://en.wikipedia.org/wiki/Zip_(file_format) http://www.pkware.com/documents/casestudies/APPNOTE.TXT

Jak ja to widzę, mogę skanować tylko poprzez danych Zip, zidentyfikować przez nagłówku jaką jestem w punkcie, a następnie zrobić aż Uderzyłem w nagłówek katalogu centralnego. Oczywiście wcześniej przeczytałem nagłówki plików i użyłem "skompresowanego rozmiaru", aby pominąć rzeczywiste dane, a nie pętli przez każdy bajt w pliku ...

Jeśli zrobię to w ten sposób, to praktycznie już znasz wszystkie pliki i foldery wewnątrz pliku Zip, w którym to przypadku nie widzę już większego użytku dla katalogu centralnego.

Dla mojego zrozumienia celem Katalogu Centralnego jest lista metadanych pliku i pozycja rzeczywistych danych w pliku Zip, aby nie trzeba było skanować całego pliku?

Po przeczytaniu o koniec zapisu Central Directory, Wikipedia mówi:

Ten Zamawiający dopuszcza plik zip ma zostać utworzony w jednym przejściu, ale jest zwykle rozpakowane przez pierwsze czytanie katalog centralny w koniec.

Jak mogę łatwo znaleźć zapisanie Koniec Centralnego Katalogu? Musimy pamiętać, że może mieć tam komentarz o dowolnym rozmiarze, więc mogę nie wiedzieć, ile bajtów pochodzi z końca strumienia danych, w którym się znajduje. Czy po prostu to skanuję?

P.S. Piszę czytnik plików Zip.

+0

Nie można rozpocząć skanowania od końca (katalog ZIP znajduje się na końcu pliku)? –

+1

Tak, mogę, ale czy naprawdę tak właśnie powinieneś to zrobić?Skanowanie do tyłu w celu znalezienia Koniec Centralnego Katalogu jest możliwe, ale biorąc pod uwagę fakt, że ma on zmienne pole komentarza o rozmiarze 16 bitów, możesz mieć około 65 tysięcy komentarzy, które musisz przeczytać/zeskanować, a jeśli komentarz zawiera magiczną liczbę, której skanowanie zakończy się niepowodzeniem. – Tower

+0

komentarze są najczęściej puste i co to jest 64K? –

Odpowiedz

1

Skończyło się na zapętleniu bajtów począwszy od końca. Pętla zatrzymuje się, jeśli znajdzie zgodną sekwencję bajtów, indeks jest poniżej zera lub jeśli już przekroczył 64 KB.

+0

Czy znalazłeś rozwiązanie? Jak wygląda centralny katalog? Mam plik zakodowany w base64. –

8

Rozpocznij na końcu i zeskanuj do początku, szukając końca sygnatury katalogu i licząc liczbę zeskanowanych bajtów. Po znalezieniu kandydata uzyskaj przesunięcie o 20 bajtów dla długości komentarza (L). Sprawdź, czy L + 20 pasuje do aktualnej liczby. Następnie sprawdź, czy początek katalogu centralnego (wskazanego przez offset 12 bajtu) ma odpowiedni podpis.

Jeśli założyłeś, że bity były całkiem przypadkowe, gdy sprawdzenie podpisu było przypadkiem (np. Odgadnięcie odgadnięcia segmentu danych), prawdopodobieństwo uzyskania wszystkich poprawnych bitów podpisu jest dość niskie. Możesz zawęzić to i znaleźć szansę na lądowanie w segmencie danych i szansę trafienia w uzasadniony nagłówek (w zależności od liczby takich nagłówków), ale to już brzmi jak małe prawdopodobieństwo dla mnie. Możesz zwiększyć swój poziom pewności, sprawdzając podpis pod pierwszym rekordem pliku, ale pamiętaj o obsłudze przypadku granicznego pustego pliku zip.

+1

Dzięki za tę odpowiedź Derek, naprawdę doceniam to. –

+0

Należy również wspomnieć, że najlepiej jest zacząć od pozycji 'endOfFile - 22', ponieważ prawdziwy koniec centralnego katalogu znaków nie może wystąpić po tej pozycji. Dla archiwów z pustymi komentarzami znajdzie podpis w pierwszej iteracji. – Mark

+0

Sprawdziłem na endOfFile -22, jeśli to się nie powiedzie, spróbuj endOfFile - 64k - 22 i wykonaj pętlę aż endOfFile -22 zastosuje tę heurystyczną kontrolę w dowolnym momencie, gdy zobaczę podpis. Kod tutaj dla ciekawskich: https://github.com/paulsapps/msgi/blob/840857346a84efc0b29ae00edb0b693b805ae4f1/Source/MgsLib/Fs.cpp#L323 – paulm

1

Po prostu skrzyżuj palce i mam nadzieję, że nie ma wpisu z CRC, znacznikiem czasu lub datownikiem jako 06054B50, ani żadnej innej sekwencji czterech bajtów, które są 06054B50.

+3

Naprawdę nie sądzę, że to dodało coś strasznie konstruktywnego do tego pytania. Byłoby lepiej dodane jako komentarz. –