program story

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

inputbox 2020. 8. 16. 20:15
반응형

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하는 대신

For gzip data with gzip header you can use gzip module directly; but please remember that under the hood, gzip uses zlib.

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

The structure of zlib and gzip is different. zlib uses RFC 1950 and gzip uses RFC 1952, so have different headers but the rest have the same structure and follows the RFC 1951.

참고URL : https://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream-with-zlib

반응형