我已经在Python中创建了zlib压缩的数据,如下所示:我想解压缩外壳中的数据。 echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/datazcat都不起作用:不幸的是,我在gzip手册页中看不到任何解压缩此类原始数据的选项,并且zlib软件包不包含任何可执行实用程序。

是否存在用于解压缩zlib原始数据的实用程序? >

评论

这里还有许多其他答案:stackoverflow.com/questions/3178566/deflate-command-line-tool

#1 楼

如果没有,或者想要使用openssl或其他工具,也可以使用标准的shell脚本+ gzip对其进行解压缩。诀窍是在gzip魔术数字和compress方法之前添加zlib.compress的实际数据:

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


编辑:
@ d0sboots评论:对于RAW Deflate数据,您需要再添加2个空字节:→"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"

> SO上的此问题提供了有关此方法的更多信息。那里的答案表明还存在一个8字节的页脚。 />
@ tobias-kienzler建议了bashrc此功能:zlipd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - $@ |gzip -dc)

评论


gzip不起作用,但是zlib-flate起作用(pdf页面内容流)。

–达涅尔·雅伊茨科夫(Daneel Yaitskov)
17年5月16日在12:23

#2 楼

zlib-flate -uncompress < IN_FILE > OUT_FILE

我尝试过,对我有用。
zlib-flate可在软件包qpdf中找到(根据其他答案的评论,在Debian Squeeze和Fedora 23中)
(感谢用户@tino谁在OpenSSL答案下方提供了此评论作为注释。将其做成适当的答案以方便访问。)

评论


与其他答案相反,此答案适用于OSX。

– polym
15年12月29日在18:32

@polym,您是如何在macOS上安装zlib-flate的?我什么都看不到。

–通配符
16-10-2在4:34

@Wildcard很抱歉收到您的回复。我认为它是随我在上面的评论中提到的brew安装的qpdf软件包一起提供的-或者查看此答案的最后一句话:)。另外,qpdf真的很酷,所以如果有时间的话,也可以看看它!

– polym
16-10-16在13:28



brew install qpdf,然后上面列出的命令:-)谢谢!

–费尔南多·加布里埃利
19-09-18在15:13

如果您正在学习如何存储git对象,那么这非常有用,使用它代替git cat-file -p可以正常工作!

–罗德里罗克
20年1月21日在22:36

#3 楼

我找到了一种解决方案(可能的一种),它正在使用openssl:

$ openssl zlib -d < /tmp/data




$ openssl zlib -d -in /tmp/data


*注意:zlib功能显然在最新的opensl版本> = 1.0.0中可用(必须使用zlib或zlib-dynamic选项配置/构建OpenSSL,后者是默认选项)

评论


在Debian Squeeze(具有OpenSSL 0.9.8)上,qpdf软件包中包含zlib-flate。可以像zlib-flate -uncompress
– Tino
2012年9月16日14:09



zlib已从最新版本的OpenSSL中删除,因此此提示对@Tino很有帮助

–亚历山大·库里林(Alexandr Kurilin)
2014年12月2日上午10:59

谢谢。与使用“ gzip”的答案相比,此解决方案在解压缩短输入文件时提供了更好的体验(“ openssl”已尽可能地解压缩,而“ gzip”则中止了“意外的文件结尾”的打印)。

–丹尼尔·K。
2015年9月16日上午10:01

@Tino这应该是一个单独的答案

–卡特斯克尔
2015年11月1日,下午3:16

@Tino,也可以通过Fedora 23上的qpdf软件包获得。Alexandr Kurilin,zlib仍以1.0.2d-fips版本提供。

–maxschlepzig
15年11月24日在8:37

#4 楼

我推荐zlib压缩库的合著者Mark Adler的Pigz。执行pigz以查看可用的标志。

您会注意到:

-z --zlib Compress to zlib (.zz) instead of gzip format.

您可以使用-d标志解压缩: br /> -d --decompress --uncompress Decompress the compressed input.

假设文件名为“ test”:



pigz -z test-创建一个名为test.zz的zlib压缩文件>
pigz -d -z test.zz-将test.zz转换为解压缩的测试文件

在OSX上,可以执行brew install pigz

评论


好发现!看起来它可以单独检测zlib文件,因此unpigz test.zz也可以正常工作。

–StéphaneChazelas
16-09-26在12:55

没有解压缩我的数据。

–cybernard
19年1月26日在1:09

@cybernard也许您没有zlib文件。检查以下内容:$> file hello.txt.zz hello.txt.zz:zlib压缩数据

–snodnipper
19年2月1日在12:08

与部分文件也能很好地工作。

–乔DF
20 Mar 5 '20 at 16:52

#5 楼

zlib实现gzip使用的压缩,但不实现文件格式。相反,您应该使用gzip模块,该模块本身使用zlib

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


评论


好的,但是我的情况是我创建了成千上万的文件,所以.. :)

–mykhal
2011-09-20 22:14

所以...您的文件不完整。如果您仍然没有原始数据,也许必须使用zlib解压缩它们并使用gzip重新压缩它们。

– Greg Hewgill
2011-09-20 22:18

@mykhal,为什么在检查是否可以真正解压缩文件之前创建十万/十万个文件?

– Harpyon
2011-09-20 22:19

harpyon,我可以解压缩它们,我只是想知道,如果我不想再次在python中使用它,可以使用哪些更少或更多的通用性或zgip设置

–mykhal
2011-09-20 22:47

#6 楼

Mark Adler本人在此处找到的示例程序zpipe.c(与zlib库的源分发一起提供)对于使用原始zlib数据的这些情况非常有用。用cc -o zpipe zpipe.c -lz编译并解压缩:zpipe -d < raw.zlib > decompressed。它也可以在没有-d标志的情况下进行压缩。

#7 楼

在完全兼容POSIX的UNIX(已正式认证!)的macOS上,OpenSSL不支持zlib,也没有zlib-flate,并且第一个解决方案与所有Python解决方案一样有效,第一个解决方案要求ZIP数据必须文件中的所有其他解决方案会迫使您创建Python脚本。

这是一个基于Perl的解决方案,可以用作命令行单行代码,通过STDIN管道获取输入,并且可以与新安装的macOS一起使用:

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


Nicer格式,Perl脚本如下:

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


#8 楼

可以这样做:

import glob
import zlib
import sys

for filename in sys.argv:
    with open(filename, 'rb') as compressed:
        with open(filename + '-decompressed', 'wb') as expanded:
            data = zlib.decompress(compressed.read())
            expanded.write(data)


然后像这样运行它:

$ python expander.py data/*


评论


谢谢,我知道zlib.decompress。大概我会用一些步行功能。我不确定shell是否可以使用glob通配符处理我大量的文件:)

–mykhal
2011-09-20 22:28

使用shell file命令,由扩展程序创建的文件是否仍以“ zlib压缩数据”的形式签出?那个怎么样?

– K.-Michael Aye
18年11月30日在0:18

即使使用伪造的标头,nope对我也不起作用。

–cybernard
19年1月26日在1:02

#9 楼

您可以使用它与zlib一起压缩:

openssl enc -z -none -e < /file/to/deflate


然后压缩:

openssl enc -z -none -d < /file/to/deflate


评论


在Ubuntu 16.04和OpenSSL 1.0.2g上提供未知选项'-z'2016年3月1日

– Tino
18年5月22日在10:50

在Mac上同样的错误

– K.-Michael Aye
18年11月30日,0:13

#10 楼

在开发与eIDAS相关的代码期间,我想出了bash脚本,该脚本解码SSO(SingleSignOn)SAMLRequest参数,该参数通常由base64和raw-deflate(php gzdeflate)编码。 =“ lang-bsh prettyprint-override”> #!/bin/bash # file decode_saml_request.sh urldecode() { : "${*//+/ }"; echo -e "${_//%/\x}"; } if [[ $contents == *"SAMLRequest" ]]; then # extract param SAMLRequest from URL, strip all following params contents=$(cat | awk -F 'SAMLRequest=' '{print }' | awk -F '&' '{print }') else # work with raw base64 encoded string contents=$(cat ) fi # add gzip raw-deflate header bytes and gunzip (`gzip -dc` can be replaced by `gunzip`) printf "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00" | cat - <(echo `urldecode $contents` | base64 -d) | gzip -dc

您可以像

 > decode_saml_request.sh /path/to/file_with_sso_url
# or
> echo "y00tLk5MT1VISSxJBAA%3D" | decode_saml_request.sh
一样使用它


脚本也在这里按gist发行:https://gist.github.com/smarek/77dacb9703ac8b715b5eced5314d5085,所以我可能不会保留此答案,但我会保留源gist >

#11 楼

对于需要适当的页眉和页脚(从zlib到gzip的实际转换)的人,我还添加了@Alex Stragies转换。
使用上述方法之一可能会更容易,但是如果读者有像我这样的情况,需要将zlib转换为gzip而不进行解压缩和重新压缩,这就是这样做的方法。
根据RFC1950 / 1952,zlib文件只能有一个流或成员。这与gzip的不同之处在于:

gzip文件由一系列“成员”(压缩数据集)组成。 ...成员只是在文件中一个接一个地出现,
在它们之前,之间或之后没有其他信息。

这意味着尽管单个zlib文件始终可以转换到单个gzip文件,则严格来说并非如此。需要注意的地方。
zlib同时具有页眉(2个字节)和页脚(4个字节),必须将其从数据中删除,以便可以附加gzip标头和页脚。一种实现方法如下:
# Remove zlib 4 byte footer
trunc_size=$(ls -l infile.z | awk '{print  - 4}')
truncate -s $trunc_size infile.z


# Remove zlib 2 byte header
dd bs=1M iflag=skip_bytes skip=2 if=infile.z of=tmp1.z

现在我们只有原始数据,可以追加gzip标头(来自@Alex Stragies)。
printf "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00" | cat - tmp1.z > tmp2.z

gzip页脚为8个字节长。它由未压缩文件的CRC32以及未压缩mod 2 ^ 32文件的大小组成,均为大字节序格式。如果您不了解这些内容,但有办法获取未压缩的文件:
generate_crcbig() {
    crc=$(crc32 $uncompressedfile)
    crcbig=$(echo "\x${crc:6:2}\x${crc:4:2}\x${crc:2:2}\x${crc:0:2}")
}

generate_lbig () {
    leng=$(ls -l $uncompressedfile | awk '{print }')
    lmod=$(expr $leng % 4294967296) # mod 2^32
    lhex=$(printf "%x\n" $lmod)
    lbig=$(echo "\x${lhex:6:2}\x${lhex:4:2}\x${lhex:2:2}\x${lhex:0:2}")
}

,然后可以将页脚附加为:是gzip格式!可以使用gzip -t outfile.gz进行验证,并且可以使用任何符合gzip规范的应用程序进行压缩。

#12 楼

Mark Adler自己在zlib数据包的contrib / puff中找到的简单的充气程序pufftest.c可以处理原始zlib数据,而无需头字节和Adler32校验和。用cc -o pufftest puff.c pufftest.c编译并充气:pufftest < raw.zlib > decompressed。请注意,它无法放气。

#13 楼

我知道作者不想使用Python,但我相信Python3 1-liner是大多数Linux用户的自然选择,所以就在这里:
python3 -c 'import sys,zlib; sys.stdout.write(zlib.decompress(sys.stdin.buffer.read()).decode())' < $COMPRESSED_FILE_PATH

#14 楼

zcat -f infile > outfile 


在fedora25上为我工作

评论


zcat仅适用于gzip格式的文件。

– Anthony Geoghegan
17-10-17在8:50