2012-07-23 4 views
1

각 바이트를 읽음으로써 zip 파일 (파이썬 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

+1

조작 된/악의적 인 zip을 분석하려고 시도했지만 파일 헤더를 수동으로 확인해야합니다. (unfortunatly) –

+0

비트와 관련이 없지만이 모든 비트 처리는 - struct 모듈을 참조하십시오. – lazy1

답변

1

당신은 블록 "중앙 디렉토리의 끝"를 뒤로 파일을 통해 검색 할 -

이것은 내가 지금 가지고있는 것입니다. 중앙 디렉토리의 총 항목 수를 포함합니다. 대한

검색 "중앙 디렉토리 레코드의 끝"에서 : http://www.pkware.com/documents/casestudies/APPNOTE.TXT

, 당신은 "중앙 디렉토리의 ZIP64 종료"를 검색하기 위해 중앙 디렉토리 = 0xffff가 항목의 총수가있는 경우 블록 "중앙 디렉토리의 끝"블록 바로 앞에 위치합니다. 이 경우 Zip64 블록에는 zip 파일의 중앙 디렉토리에있는 실제 항목 수가 포함됩니다.

"EofCD"블록에는 중앙 디렉터리의 시작 부분에 대한 오프셋이 포함되어 있습니다.이 오프셋을 사용하면 전체 중앙 디렉터리의 모든 파일 헤더 블록을 반복 할 수 있습니다.

+0

헤더의 시작 부분 인 'PK'를 검색 할 수 있기 때문에 효과가 있다고 생각합니다. –

+0

좋아, 이걸 시도하고 돌아올거야 ... 고마워! –

+0

"PK"이상을 찾고 싶습니다. appnote에 따라 0x06054b50 인 "EofCD"블록의 서명을 검색하려고합니다. –

관련 문제