[gzip] zlib로 gzip 스트림의 압축을 풀려면 어떻게해야합니까?

gzip예를 들어 프로그램으로 만든 Gzip 형식 파일 은 zlib가 사용 하는 것과 동일한 압축 알고리즘 인 “deflate”압축 알고리즘을 사용합니다. 그러나 zlib를 사용하여 gzip 압축 파일을 부 풀릴 때 라이브러리는 Z_DATA_ERROR.

zlib를 사용하여 gzip 파일의 압축을 풀려면 어떻게해야합니까?



답변

zlib를 사용하여 gzip 형식 파일의 압축을 풀려면 다음 inflateInit2과 같이 windowBits매개 변수를으로 호출 16+MAX_WBITS합니다.

inflateInit2(&stream, 16+MAX_WBITS);

이렇게하지 않으면 zlib는 잘못된 스트림 형식에 대해 불평합니다. 기본적으로 zlib는 zlib 헤더로 스트림을 생성하며 inflate에서는 사용자가 지정하지 않는 한 다른 gzip 헤더를 인식하지 못합니다. 이것은 zlib.h헤더 파일 의 버전 1.2.1부터 문서화되어 있지만 zlib 매뉴얼 에는 없습니다 . 헤더 파일에서 :

windowBits선택적인 gzip 디코딩의 경우 15보다 클 수도 있습니다. windowBits자동 헤더 감지로 zlib 및 gzip 디코딩을 활성화 하려면 에 32를 추가하고 gzip 형식 만 디코딩하려면 16을 추가하십시오 (zlib 형식은를 반환합니다 Z_DATA_ERROR). gzip 스트림이 디코딩되는 strm->adler경우 adler32 대신 crc32입니다.


답변

파이썬

zlib도서관 지원 :

파이썬 zlib모듈은 이것도 지원합니다.

windowBits 선택

그러나 zlib이러한 모든 형식의 압축을 풀 수 있습니다.

  • deflate형식 을 (해제) 압축 하려면wbits = -zlib.MAX_WBITS
  • zlib형식 을 (해제) 압축 하려면wbits = zlib.MAX_WBITS
  • gzip형식 을 (해제) 압축 하려면wbits = zlib.MAX_WBITS | 16

http://www.zlib.net/manual.html#Advanced (섹션 inflateInit2)의 문서를 참조하십시오.

테스트 데이터 :

>>> deflate_compress = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS)
>>> zlib_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS)
>>> gzip_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16)
>>>
>>> text = '''test'''
>>> deflate_data = deflate_compress.compress(text) + deflate_compress.flush()
>>> zlib_data = zlib_compress.compress(text) + zlib_compress.flush()
>>> gzip_data = gzip_compress.compress(text) + gzip_compress.flush()
>>>

에 대한 명백한 테스트 zlib:

>>> zlib.decompress(zlib_data)
'test'

테스트 deflate:

>>> zlib.decompress(deflate_data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: incorrect header check
>>> zlib.decompress(deflate_data, -zlib.MAX_WBITS)
'test'

테스트 gzip:

>>> zlib.decompress(gzip_data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: incorrect header check
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|16)
'test'

데이터는 gzip모듈 과도 호환됩니다 .

>>> import gzip
>>> import StringIO
>>> fio = StringIO.StringIO(gzip_data)
>>> f = gzip.GzipFile(fileobj=fio)
>>> f.read()
'test'
>>> f.close()

자동 헤더 감지 (zlib 또는 gzip)

에 추가 32하면 windowBits헤더 감지가 트리거됩니다.

>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32)
'test'
>>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32)
'test'

사용 gzip하는 대신

대한 gzipGZIP 헤더 사용할 수와 데이터 gzip를 직접 모듈을; 하지만 후드 것을 기억하시기 바랍니다 , gzip용도 zlib.

fh = gzip.open('abc.gz', 'rb')
cdata = fh.read()
fh.close()


답변

zlib와 gzip의 구조는 다릅니다. zlib는 RFC 1950 을 사용하고 gzip은 RFC 1952 를 사용하므로 헤더가 다르지만 나머지는 동일한 구조를 가지며 RFC 1951을 따릅니다 .


답변