Comment DEFLATE avec un outil de ligne de commande pour extraire un objet git?

StackOverflow https://stackoverflow.com/questions/3178566

  •  02-10-2019
  •  | 
  •  

Question

Je cherche une enveloppe de ligne de commande pour l'algorithme DEFLATE.

J'ai un fichier (blob git) qui est compressé en utilisant DEFLATE, et je veux décompresser. La commande gzip ne semble pas avoir la possibilité d'utiliser directement l'algorithme DEFLATE, plutôt que le format gzip.

Idéalement, je suis à la recherche d'un outil standard Unix / Linux qui peut le faire.

edit: Ceci est la sortie que je reçois en essayant d'utiliser gzip pour mon problème:

$ cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip

gzip: stdin: not in gzip format
Était-ce utile?

La solution

Mise à jour: Mark Adler a noté que les blobs git ne sont pas des flux de Deflate premières, mais les flux zlib. Ceux-ci peuvent être déballés par l'outil pigz, qui est pré-emballé dans plusieurs distributions Linux:

$ cat foo.txt 
file foo.txt!

$ git ls-files -s foo.txt
100644 7a79fc625cac65001fb127f468847ab93b5f8b19 0   foo.txt

$ pigz -d < .git/objects/7a/79fc625cac65001fb127f468847ab93b5f8b19 
blob 14file foo.txt!

Ma réponse originale, conservée pour des raisons historiques:

Si je comprends l'allusion dans le Wikipedia article mentionné par Marc van Kempen, vous peut utiliser puff.c zlib directement.

Ceci est un petit exemple:

#include <assert.h>
#include <string.h>
#include "puff.h"

int main( int argc, char **argv ) {
    unsigned char dest[ 5 ];
    unsigned long destlen = 4;
    const unsigned char *source = "\x4B\x2C\x4E\x49\x03\x00";
    unsigned long sourcelen = 6;    
    assert( puff( dest, &destlen, source, &sourcelen ) == 0 );
    dest[ 4 ] = '\0';
    assert( strcmp( dest, "asdf" ) == 0 );
}

Autres conseils

Quelque chose comme ce qui suit imprimera le contenu brut, y compris le "$ Type de longueur $ \ 0" en-tête:

perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' \
     < .git/objects/27/de0a1dd5a89a94990618632967a1c86a82d577

Vous pouvez le faire avec l'outil de ligne de commande OpenSSL:

openssl zlib -d < $IN > $OUT

Malheureusement, au moins sur Ubuntu, la sous zlib est désactivé dans la configuration de construction par défaut (--no-zlib --no-zlib-dynamic), de sorte que vous devrez compiler openssl de la source à utiliser. Mais il est activé par défaut sur Arc, par exemple.

Edit: On dirait la commande zlib n'est plus prise en charge Arch soit. Cette réponse pourrait ne pas être plus utile: (

pythonique one-liner:

$> python -c "import zlib,sys;print \
           repr(zlib.decompress(sys.stdin.read()))" < $IN

Vous pouvez utiliser, comme zlib-flate ceci:

cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 \
    | zlib-flate -uncompress; echo

Il est là par défaut sur ma machine, mais il fait partie de qpdf - tools for and transforming and inspecting PDF files si vous devez l'installer.

J'ai sauté une echo à la fin de la commande, car il est plus facile de lire la sortie de cette façon.

Essayez la commande suivante:

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip

Aucun outil externe est nécessaire.

Source: Comment les données décompresse zlib sous UNIX? à unix SE

Voici un Ruby one-liner (cd .git / premier et identifier chemin à un objet):

ruby -rzlib -e 'print Zlib::Inflate.new.inflate(STDIN.read)' < ./74/c757240ec596063af8cd273ebd9f67073e1208

Je suis fatigué de ne pas avoir une bonne solution pour cela, donc je mets quelque chose sur NPM:

https://github.com/jezell/zlibber

peut simplement tuyau pour gonfler / dégonfler commande.

Voici un exemple de rupture ouvert un objet commit en Python:

$ git show
commit 0972d7651ff85bedf464fba868c2ef434543916a
# all the junk in my commit...
$ python
>>> import zlib
>>> file = open(".git/objects/09/72d7651ff85bedf464fba868c2ef434543916a")
>>> data = file.read()
>>> print data
# binary garbage
>>> unzipped_data = zlib.decompress(data)
>>> print unzipped_data
# all the junk in my commit!

Ce que vous verrez, il est presque identique à la sortie de « -p cat-file git [hachage] », sauf que la commande n'imprime pas l'en-tête ( « commit » suivi de la taille du contenu et une valeur nulle octet).

On dirait Mark Adler nous a à l'esprit et écrit un exemple de comment le faire cela avec: http: //www.zlib.net/zpipe.c

Il compile avec rien de plus que gcc -lz et les en-têtes de zlib. J'ai copié le binaire résultant à mon /usr/local/bin/zpipe tout en travaillant avec des trucs git.

objets git sont comprimés par zlib plutôt que gzip, donc soit en utilisant zlib à décompresser, ou la commande git, à savoir git cat-file -p <SHA1>, pour imprimer le contenu.

// save this as deflate.go

package main

import (
    "compress/zlib"
    "io"
    "os"
    "flag"
)

var infile = flag.String("f", "", "infile")

func main() {
    flag.Parse()
    file, _ := os.Open(*infile)

    r, err := zlib.NewReader(file)
    if err != nil {
        panic(err)
    }
    io.Copy(os.Stdout, r)

    r.Close()
}

$ go build deflate.go
$ ./deflate -f .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7

Voir http://en.wikipedia.org/wiki/DEFLATE#Encoder_implementations

Il énumère un certain nombre d'implémentations de logiciels, y compris gzip, ce qui devrait fonctionner. Avez-vous essayé simplement en cours d'exécution sur le fichier gzip? Est-il reconnaît pas automatiquement le format?

Comment savez-vous qu'il est compressé en utilisant DEFLATE? Quel outil a été utilisé pour compresser le fichier?

Pourquoi ne pas utiliser simplement les outils de git pour accéder aux données? Cela devrait être capable de lire tout objet git:

git show --pretty=raw <object SHA-1>

Je trouve cette question à la recherche d'un travail autour d'un bug avec l'utilitaire -text dans la nouvelle version du client hadoop dfs Je viens d'installer. L'utilitaire -text fonctionne comme cat, sauf si le fichier en cours de lecture est compressé, il décompresse de façon transparente et transmet le texte brut (d'où le nom).

Les réponses déjà affichées sont certainement utiles, mais certains d'entre eux ont un problème lorsqu'ils traitent avec des quantités Hadoop taille de données -. Ils lisent tout en mémoire avant la décompression

Alors, voici mes variations sur les réponses de Perl et Python ci-dessus qui n'ont pas cette limitation:

Python:

hadoop fs -cat /path/to/example.deflate |
  python -c 'import zlib,sys;map(lambda b:sys.stdout.write(zlib.decompress(b)),iter(lambda:sys.stdin.read(4096),""))'

Perl:

hadoop fs -cat /path/to/example.deflate |
  perl -MCompress::Zlib -e 'print uncompress($buf) while sysread(STDIN,$buf,4096)'

Notez l'utilisation de la sous-commande -cat, au lieu de -text. Il en est ainsi que mon travail autour ne rompt pas après avoir résolu le bug. Toutes mes excuses pour la lisibilité de la version python.

objets git sont des flux zlib (non deflate brut). pigz décompresse ceux avec l'option -dz.

pigz peut le faire:

apt-get install pigz
unpigz -c .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7
const zlib = require("zlib");
const adler32 = require("adler32");
const data = "hello world~!";
const chksum = adler32.sum(new Buffer(data)).toString(16);
console.log("789c",zlib.deflateRawSync(data).toString("hex"),chksum);
// or
console.log(zlib.deflateSync(data).toString("hex"));

Pour ajouter à la collection, voici une seule ligne perl pour dégonfler / gonflent / dégonfler premières / inflate brut.

Deflate

perl -MIO::Compress::Deflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Compress::Deflate::deflate(\$in, \$out); print $out;'

Gonfler

perl -MIO::Uncompress::Inflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Uncompress::Inflate::inflate(\$in, \$out); print $out;'

Raw dégonfler

perl -MIO::Compress::RawDeflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Compress::RawDeflate::rawdeflate(\$in, \$out); print $out;'

inflate Raw

perl -MIO::Uncompress::RawInflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Uncompress::RawInflate::rawinflate(\$in, \$out); print $out;'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top