UNIX에서 zlib 데이터의 압축을 푸는 방법은 무엇입니까?

UNIX에서 zlib 데이터의 압축을 푸는 방법은 무엇입니까?

다음과 같이 Python에서 zlib 압축 데이터를 만들었습니다.

import zlib
s = '...'
z = zlib.compress(s)
with open('/tmp/data', 'w') as f:
    f.write(z)

(또는 쉘의 한 줄 echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/data:)

이제 쉘에서 데이터의 압축을 풀고 싶습니다. 작동하지도 zcat않습니다 uncompress.

$ cat /tmp/data | gzip -d -
gzip: stdin: not in gzip format

$ zcat /tmp/data 
gzip: /tmp/data.gz: not in gzip format

$ cat /tmp/data | uncompress -
gzip: stdin: not in gzip format

gzip과 유사한 파일을 생성했지만 헤더가 없는 것 같습니다. 불행하게도 gzip 매뉴얼 페이지에는 그러한 원시 데이터의 압축을 풀기 위한 옵션이 없으며 zlib 패키지에는 실행 가능한 유틸리티가 포함되어 있지 않습니다.

원시 zlib 데이터의 압축을 풀 수 있는 유틸리티가 있습니까?

답변1

표준을 사용하여 압축을 풀 수도 있습니다.+, 가지고 있지 않거나 사용하고 싶은 경우또는 다른 도구.
비결은 미리 추가하는 것이다.gzip 매직 넘버와 압축 방법실제 데이터 출처 zlib.compress:

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - /tmp/data |gzip -dc >/tmp/out

편집:
@d0sboots 의견: RAW Deflate 데이터의 경우 null 바이트를 2개 더 추가해야 합니다.
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"

SO에 대한 이 질문이 방법에 대한 자세한 내용을 확인할 수 있습니다. 거기에 대한 답변은 8바이트 바닥글도 있음을 나타냅니다.

@Vitali-Kushner 및 @mark-bessey 사용자는 파일이 잘린 경우에도 성공을 보고하므로 gzip 바닥글이 엄격하게 요구되지는 않는 것 같습니다.

@tobias-kienzler는 이 기능 사용을 제안했습니다.:
zlibd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - "$@" | gzip -dc)

답변2

zlib-flate -uncompress < IN_FILE > OUT_FILE

나는 이것을 시도했고 그것은 나를 위해 일했습니다.

zlib-flate패키지에서 찾을 수 있습니다 qpdf(다른 답변의 의견에 따라, Debian Squeeze, Fedora 23 및 MacOS의 Brew에서)

(OpenSSL 답변 아래에 이 의견을 제공한 @tino 사용자에게 감사드립니다. 더 쉽게 액세스할 수 있도록 정답으로 만들었습니다.)

답변3

다음을 사용하는 솔루션(가능한 솔루션 중 하나)을 찾았습니다.OpenSSL:

$ openssl zlib -d < /tmp/data

또는

$ openssl zlib -d -in /tmp/data

*참고: zlib 기능은 최신 openssl 버전 >= 1.0.0에서 사용 가능한 것으로 보입니다(OpenSSL은 zlib 또는 zlib-dynamic 옵션으로 구성/구축되어야 하며 후자가 기본값입니다).

답변4

POSIX와 완전히 호환되는 UNIX(공식적으로 인증됨!)인 macOS에서는 둘 다 지원 되지 OpenSSL않습니다 . 첫 번째 솔루션은 모든 Python 솔루션과 마찬가지로 작동하지만 첫 번째 솔루션에서는 ZIP 데이터가 다음 위치에 있어야 합니다. 파일을 사용하면 Python 스크립트를 생성해야 합니다.zlibzlib-flate

다음은 명령줄 단일 라이너로 사용할 수 있고, STDIN 파이프를 통해 입력을 받고, 새로운 macOS 설치 시 즉시 사용할 수 있는 Perl 기반 솔루션입니다.

cat file.compressed | perl -e 'use Compress::Raw::Zlib;my $d=new Compress::Raw::Zlib::Inflate();my $o;undef $/;$d->inflate(<>,$o);print $o;'

Perl 스크립트는 다음과 같은 형식으로 구성하는 것이 더 좋습니다.

use Compress::Raw::Zlib;
my $decompressor = new Compress::Raw::Zlib::Inflate();
my $output;
undef $/;
$decompressor->inflate(<>, $output);
print $output;

Marco d'Itri의 최적화된 버전(댓글 참조):

cat file.compressed | perl -MCompress::Zlib -E 'undef $/;print uncompress(<>)'

관련 정보