2012-07-23 74 views
1

我想通過讀取每個字節來讀取一個zip文件(在python 2.7.2中)。我能夠通過本地文件頭和數據。但是,當我嘗試讀取中央文件頭時,我卡住了。確定一個zip中有多少個文件

這幫助了很多http://en.wikipedia.org/wiki/File:ZIP-64_Internal_Layout.svg

我不知道如何找出有多少項有存檔,所以我可以切換到在格式化中央文件頭或要不然怎麼知道如何從格式化文件切換到中央文件頭。

這就是我現在所擁有的 -

import sys 

def main(debug=0,arg_file=''): 
    if debug==2: 
     print "- Opening %s" % arg_file 
    with open(arg_file) as archive: 
     if debug==2: 
      print "- Reading %s" % arg_file 

     bytes = archive.read() 
     if debug==2: 
      print "-------------Binary-------------" 
      print bytes 

     #Read file headers 
     end = 0 
     while end != bytes.__len__(): 
      print end 
      end = process_sub_file(debug,end,bytes) 

def process_sub_file(debug,startbytes, bytes): 
    header = bytes[startbytes + 0] + bytes[startbytes + 1] + bytes[startbytes + 2] + bytes[startbytes + 3] 
    version = bytes[startbytes + 4] + bytes[startbytes + 5] 
    flags = bytes[startbytes + 6] + bytes[startbytes + 7] 
    comp_method = bytes[startbytes + 8] + bytes[startbytes + 9] 
    mod_time = bytes[startbytes + 10] + bytes[startbytes + 11] 
    mod_date = bytes[startbytes + 12] + bytes[startbytes + 13] 
    crc = bytes[startbytes + 14] + bytes[startbytes + 15] + bytes[startbytes + 16] + bytes[startbytes + 17] 
    comp_size_bytes = bytes[startbytes + 18] + bytes[startbytes + 19] + bytes[startbytes + 20] + bytes[startbytes + 21] 
    comp_size = ord(comp_size_bytes[0]) + ord(comp_size_bytes[1]) + ord(comp_size_bytes[2]) + ord(comp_size_bytes[3]) 
    uncomp_size_bytes = bytes[startbytes + 22] + bytes[startbytes + 23] + bytes[startbytes + 24] + bytes[startbytes + 25] 
    uncomp_size = ord(uncomp_size_bytes[0]) + ord(uncomp_size_bytes[1]) + ord(uncomp_size_bytes[2]) + ord(uncomp_size_bytes[3]) 
    name_len_bytes = bytes[startbytes + 26] + bytes[startbytes + 27] 
    name_len = int(ord(name_len_bytes[0])+ord(name_len_bytes[1])) 
    extra_len_bytes = bytes[startbytes + 28] + bytes[startbytes + 29] 
    extra_len = int(ord(extra_len_bytes[0])+ord(extra_len_bytes[1])) 
    file_name = "" 
    for i in range(name_len): 
     file_name = file_name + bytes[startbytes + 30 + i] 
    extra_field = "" 
    for i in range(extra_len): 
     file_name = file_name + bytes[startbytes + 30 + name_len + i] 
    data = "" 
    for i in range(comp_size): 
     data = data + bytes[startbytes + 30 + name_len + extra_len + i] 
    if debug>=1: 
     print "-------------Header-------------" 
     print "Header Signature: %s" % header 
     print "Version: %s" % version 
     print "Flags: %s" % flags 
     print "Compression Method: %s" % comp_method 
     print "Modification Time: %s" % (ord(mod_time[0]) + ord(mod_time[1])) 
     print "Modification Date: %s" % (ord(mod_date[0]) + ord(mod_time[1])) 
     print "CRC-32: %s" % crc 
     print "Compressed Size: %s" % comp_size 
     print "Uncompressed Size: %s" % uncomp_size 
     print "File Name Length: %s" % name_len 
     print "Extra Field Length: %s" % extra_len 
     print "File Name: %s" % file_name 
     print "Extra Field: %s" % extra_field 
     print "Data:\n%s" % data 
    return startbytes + 30 + name_len + extra_len + comp_size 
+1

有沒有原因你不使用內置的'zipfile'模塊? – lazy1 2012-07-23 22:33:35

+1

我試圖分析/發現畸形/惡意拉鍊,我需要手動檢查文件頭(不幸) – 2012-07-23 22:34:40

+0

有點不相干,但是對於所有這些位處理 - 請參閱'struct'模塊。 – lazy1 2012-07-23 22:38:30

回答

1

你想通過文件向後搜索塊「中央目錄的結尾」。它包含中央目錄中的條目總數。

搜索「中央目錄記錄的結尾:」在: http://www.pkware.com/documents/casestudies/APPNOTE.TXT

如果條目在中央目錄= 0xFFFF的總數,那麼你要搜索「中央目錄的Zip64結尾」塊它位於「中央目錄結束」塊之前。在這種情況下,Zip64塊將包含zip文件中央目錄中的實際條目數。

「EofCD」塊包含中央目錄開始的偏移量,然後您可以開始遍歷整個中央目錄中的所有文件頭塊。

+0

我認爲這將起作用,因爲我能夠搜索作爲標題開頭的'PK'。 – 2012-07-23 22:37:31

+0

好吧我會試試這個,回來...謝謝你! – 2012-07-23 22:38:20

+0

您想要搜索的不僅僅是'PK'。您需要搜索「EofCD」塊的簽名,該塊根據appnote是0x06054b50。 – 2012-07-23 22:44:14

相關問題