2013-03-29 1 views
1

압축 된 내용과 32 바이트 헤더로 구성된 파일이 있습니다. 헤더에는 타임 스탬프, 압축 된 크기 및 압축되지 않은 크기와 같은 정보가 들어 있습니다.zlib가 X 바이트 이상 압축을 풀지 않게하는 방법은 무엇입니까?

파일 자체는 약 490MB이고 압축되지 않은 크기는 2.7GB에 가깝다는 것을 나타내는 헤더가 있습니다 (압축 된 크기가 752MB라고 믿기 때문에 분명히 잘못되었습니다).

헤더를 제거하고 압축 된 페이로드를 생성했으며 zlib로 압축을 풀 수 있습니다.

문제는 단지 19kb를 압축 해제하는 것인데, 490mb보다 훨씬 작습니다 (최소한 압축해야하지만, 압축되지 않은 상태로 약 700mb가 필요합니다).

내 코드는 다음과 같습니다 :

import zlib 

def consume (inputFile): 
    content = inputFile.read() 
    print "Attempting to process " + str(len(content)) + " bytes..." 
    outfile = open('output.xml', 'w') 
    inputFile = zlib.decompress(content) 
    print "Attempting to write " + str(len(inputFile)) + " bytes..." 
    outfile.write(inputFile) 
    outfile.close() 

infile = open('payload', 'rb') 

consume(infile) 

infile.close() 

실행

프로그램 출력 :

489,987,232 바이트를 처리하기 위해 시도

... 18,602 바이트를 작성하려고 ...

나는 잘못된 헤더 경고를 생성하지만 zlib.decompressionobj()을 사용하려고했습니다. zlib.decompress() 잘 작동하고 내가 예상했던 압축 해제 된 XML을 생성합니다 ... 너무 적습니다.

모든 의견이나 제안을 보내 주시면 대단히 감사하겠습니다.

+0

파일의 출처는 어디입니까? 필요에 따라 다시 다운로드하거나 이전 버전으로 롤백하거나 백업에서 복원 할 수 있습니까? – abarnert

+0

Th 파일은 그 내용에 대한 격렬한 설명에서 분명히 손상된 것으로 들립니다. – nneonneo

+0

@abarnert 파일은 파트너 사 (dropbox 이상)에서 제공했습니다. 나는 다른 것을 얻고 그것을 시도 할 수 있습니다. 포인터를 주셔서 감사합니다 - 내 코드 또는 메서드가 잘못되었다고 가정하고 있었지만, 큰 도움이 될 파일로 판명되면! – jscarto

답변

3

분명히 손상된 파일이 있습니다.

zlib가 손상을 무시하도록 강요 할 수 없으며, 그렇게했다면 700MB의 쓰레기 또는 임의의 쓰레기가 발생할 가능성이 높습니다. 부패가 어디서 발생했는지. 그러나 당신이 쓸모있는 것을 얻을 수있는 기회는 꽤 희박합니다.

zlib의 블록은 임의 액세스가 가능하지 않거나 구분되거나 심지어는 바이트 정렬되지 않습니다. 이전 블록을 처리 할 수 ​​없다면 다음 블록에 도달 한 시점을 알기가 매우 어렵습니다.

게다가 나무는 블록 단위로 자라기 때문에 다음 블록으로 건너 뛸 수 있다고해도 나무가 잘못 될 수 있습니다. 매우 운이 좋고 필요하지 않으면 쓰레기를 감압해야합니다. 나무의 깨진 부분. 더 나쁜 것은 모든 블록이 트리를 재시작 할 수 있다는 것입니다 (또는 압축기를 전환 할 수도 있습니다). 이 누락 된 경우 일 경우 일을 수행해도 일 경우 쓰레기를 감압하고 있습니다. 매우 운이 좋습니다. 그리고 "이 문자열을 인식하지 못하기 때문에이 문자열을 건너 뛰는"문제가 아닙니다. 인식하지 못하면 문자열의 길이가 얼마인지 알지 못하기 때문에 건너 뛸 수 없습니다. 첫 번째로 되돌아 가면 하나의 문자열을 건너 뛸 수 없으며 전체 블록이 훨씬 적습니다.

더 잘 이해하려면 zlib에서 사용되는 형식을 설명하는 RFC 1951을 참조하십시오. 몇 가지 사소한 예를 통해 수동으로 시도해보십시오 (첫 번째 블록의 몇 개의 문자열, 두 번째 블록의 두 개의 새로운 문자열). 실행 취소하기가 쉬운 방식으로 손상시키는 것이 얼마나 쉬운 지 알 수 있습니다 (정확하게 부패했다).은 불가능합니다. (결국 암호화 된 메시지를 암호화하는 것은 불가능하지 않습니다.)하지만 완전히 자동화 될 수 있다고는 생각하지 않습니다. 재미 있지는 않을 것입니다.

중요한 데이터가 있고 (다시 다운로드 할 수없고 이전 버전으로 롤백하고 백업에서 복원 할 수없는 경우) 일부 데이터 복구 서비스는 손상된 zlib/gz/zip 파일. 나는이 비용이 팔과 다리를 가졌다 고 생각하지만 올바른 데이터에 대한 올바른 대답 일 수 있습니다.

그리고 물론 나는 이것이 자동화 될 수 없다는 점에서 잘못 될 수 있습니다. Zip 복구 도구가 많이 있습니다. 내가 아는 한, 깨진 zlib 스트림으로 수행 할 수있는 작업은 해당 파일을 건너 뛰고 다른 파일을 복구하는 것입니다. 그러나 어쩌면 일부 파일에는 손상된 스트림이있는 경우도 있습니다.

+0

이것은 많은 의미가 있습니다 - 상세한 답장과 링크에 감사드립니다! 데이터가 테스트 케이스로 제공되었으므로 다시 획득하고 다시 시도 할 수 있어야합니다 (손가락을 계속 지탱하십시오). – jscarto

+0

잠시 휴식을 취한 후에 문제를 확인했습니다. 데이터가 손상되지 않은 것으로 밝혀졌습니다. 대신, 압축 파일은 여러 개의 연결된 스트림으로 구성됩니다. 따라서 객체를 한 번에 압축 해제하려는 시도는 첫 번째 스트림을 읽음으로써 작은 19kb 결과를 생성합니다. 이후로 새로운 문제가 생겼지 만 이것을 설명하기 위해 코드를 조정했습니다. 감압은 [쑥쑥 느리게]입니다 (http://stackoverflow.com/questions/16506590/python-and-zlib). -terribly-slow-decompressing-concatenated-streams)을 사용합니다. – jscarto

0

왜 정지했는지 보려면 zlib.error을 확인해야합니다. 왜 그만 했지?

관련 문제