it-swarm-eu.dev

Jak dekomprimovat data zlib v UNIXu?

Vytvořil jsem v Pythonu komprimovaná data jako zlib:

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

(nebo jednovrstvý v Shell: echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/data)

Nyní chci dekomprimovat data v Shell. zcat ani uncompress nefungují:

$ 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

Zdá se, že jsem vytvořil soubor typu gzip, ale bez záhlaví. Na manuálové stránce gzip bohužel nevidím žádnou možnost dekomprimovat taková nezpracovaná data a balíček zlib neobsahuje žádný spustitelný nástroj.

Existuje nástroj pro dekomprimaci surových dat zlib?

121
mykhal

Je také možné dekomprimovat pomocí standardního Shell-script + gzip , pokud nemáte, nebo chcete použít openssl nebo jiné nástroje.
Trik je předepsat gzip magické číslo a metoda komprese ke skutečným datům z zlib.compress:

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

Úpravy:
@ d0sboots komentoval: Pro data RAW Deflate musíte přidat další 2 nulové bajty:
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"

Toto Q na SO poskytuje více informací o tomto přístupu. Odpověď na tuto otázku naznačuje, že je zde také zápatí o velikosti 8 bajtů.

Uživatelé @ Vitali-Kushner a @ mark-bessey hlásili úspěch i se zkrácenými soubory, takže zápatí gzip se nezdá být nutně nutné.

@ tobias-kienzler navrhl tuto funkci pro bashrc :
zlipd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - [email protected] |gzip -dc)

146
wkpark
zlib-flate -uncompress < FILE

Zkusil jsem to a fungovalo to pro mě.

zlib-flate lze najít v balíčku qpdf (v Debianu Squeeze a Fedora 23, podle komentářů v dalších odpovědích)

(Díky uživateli @tino, který to poskytl jako komentář pod odpovědí OpenSSL. Vyrobeno v propper odpovědi pro snadný přístup.

81
Catskul

Našel jsem řešení (jedno z možných), používá openssl:

$ openssl zlib -d < /tmp/data

nebo

$ openssl zlib -d -in /tmp/data

* POZNÁMKA: Funkce zlib je zjevně k dispozici v nedávných verzích openssl> = 1.0.0 (OpenSSL musí být nakonfigurováno/vytvořeno pomocí zlib nebo zlib-dynamic, druhá je výchozí)

63
mykhal

Doporučuji pigz od Mark Adler , spoluautor komprimační knihovny zlib. Po spuštění pigz zobrazíte dostupné příznaky.

Všimnete si:

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

Rozbalit můžete pomocí příznaku -d:

-d --decompress --uncompress Decompress the compressed input.

Předpokládejme soubor s názvem 'test':

  • pigz -z test - vytvoří komprimovaný soubor zlib s názvem test.zz
  • pigz -d -z test.zz - převede test.zz na dekomprimovaný testovací soubor

V OSX můžete spustit brew install pigz

30
snodnipper

zlib implementuje kompresi používanou gzipem, ale ne formát souboru. Místo toho byste měli použít modul gzip , který sám používá zlib.

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

Mohlo by to udělat:

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)

Pak to spusťte takto:

$ python expander.py data/*
3
Jeremy Banks

V systémech MacOS, což je plně kompatibilní s unixovým systémem UNIX (formálně certifikováno!), OpenSSL nemá podporu zlib, neexistuje žádná zlib-flate A zatímco první řešení funguje také jako všechna řešení Python vyžaduje první řešení, aby byla data Zip v souboru a všechna ostatní řešení vás nutí vytvořit skript Python.

Zde je řešení založené na Perlu, které může být použito jako liniové příkazové řádky, získává svůj vstup pomocí STDIN kanálu a funguje mimo krabici s čerstvě nainstalovaným makrem:

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

Příjemnější formát, skript Perl vypadá takto:

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

Příklad programu zpipe.czde nalezen samotného Marka Adlera (přichází s distribucí zdroje knihovny zlib) je velmi užitečný pro tyto scénáře se surovými daty zlib. Zkompilujte s cc -o zpipe zpipe.c -lz A dekomprimujte: zpipe -d < raw.zlib > decompressed. Může také provádět kompresi bez příznaku -d.

3
Henno Brandsma

Můžete to použít ke kompresi se zlib:

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

A to deflate:

openssl enc -z -none -d < /file/to/deflate
1
Danny R

Během vývoje kódu souvisejícího s eIDAS jsem přišel s bash skriptem, který dekóduje SSO (SingleSignOn) SAMLRequest param, který je obvykle kódován base64 a raw-deflate (php gzdeflate)

#!/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 ${1} | awk -F 'SAMLRequest=' '{print $2}' | awk -F '&' '{print $1}')
else
  # work with raw base64 encoded string
  contents=$(cat ${1})
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

Můžete to použít jako

> decode_saml_request.sh /path/to/file_with_sso_url
# or
> echo "y00tLk5MT1VISSxJBAA%3D" | decode_saml_request.sh

Skript je publikován také jako Gist zde: https://Gist.github.com/smarek/77dacb9703ac8b715b5eced5314d5085 , takže si nemusím udržovat tuto odpověď, ale budu udržovat zdroj Gist

0
Marek Sebera