56 votes

Pourquoi git hash-object retourne un hachage différent de openssl sha1?

Contexte: j'ai téléchargé un fichier (Audirvana 0.7.1.zip) à partir du code.google à mon Macbook Pro (Mac OS X 10.6.6).

Je voulais vérifier la somme de contrôle, qui pour le fichier est affiché comme 862456662a11e2f386ff0b24fdabcb4f6c1c446a (SHA-1). git hash-object m'a donné un hachage différent, mais openssl sha1 a renvoyé l'attend 862456662a11e2f386ff0b24fdabcb4f6c1c446a.

L'expérience suivante semble exclure toute possibilité de télécharger de la corruption ou de saut de ligne différences, et d'indiquer qu'il y a en fait deux algorithmes différents à jouer:

$ echo A > foo.txt
$ cat foo.txt
A
$ git hash-object foo.txt 
f70f10e4db19068f79bc43844b49f3eece45c4e8
$ openssl sha1 foo.txt 
SHA1(foo.txt)= 7d157d7c000ae27db146575c08ce30df893d3a64

Ce qui se passe?

76voto

Mark Longair Points 93104

Vous voyez une différence, car git hash-object n'est pas juste un hachage de l'octet dans le fichier - il ajoute la chaîne "blob ", suivi par la taille du fichier et un NUL pour que le contenu du fichier avant le hachage. Il y a plus de détails dans cette autre réponse sur un Débordement de Pile:

Ou, pour vous en convaincre, essayez quelque chose comme:

$ echo -n hello | git hash-object --stdin
b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0

$ printf 'blob 5\0hello' > test.txt
$ openssl sha1 test.txt
SHA1(test.txt)= b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0

5voto

araqnid Points 33350

Le SHA1 digest est calculée sur une chaîne d'en-tête suivi par le fichier de données. L'en-tête comprend le type d'objet, d'un espace et de l'objet de la longueur en octets comme séparateur décimal. Il est séparé de données par un octet nul.

Donc:

$ git hash-object foo.txt
f70f10e4db19068f79bc43844b49f3eece45c4e8
$ ( perl -e '$size = (-s shift); print "blob $size\x00"' foo.txt \
               && cat foo.txt ) | openssl sha1
f70f10e4db19068f79bc43844b49f3eece45c4e8

Une conséquence de cela est que "la" arbre vide et "le" vide blob ont des Identifiants différents. C'est:

e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 toujours "fichier vide" 4b825dc642cb6eb9a060e54bf8d69288fbee4904 toujours "répertoire vide"

Vous trouverez que vous pouvez, en fait, git ls-tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 dans un nouveau dépôt git avec aucun des objets enregistrés, car il est reconnu comme un cas particulier et ne jamais réellement stocké (avec moderne Git versions). En revanche, si vous ajoutez un fichier vide pour votre repo, un blob "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391" sera conservé.

2voto

twcamper Points 123

La réponse se trouve ici:

Attribution de Git SHA1 sans Git

git calcule sur le fichier les métadonnées + le contenu, pas seulement le contenu.

C'est une bonne réponse pour l'instant, et la conclusion est que git n'est pas l'outil de contrôle de la somme des téléchargements.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X