Różne sumy md5 dla tej samej zawartości tar

15

Przeprowadzam test, tworząc dwa smoły z tego samego katalogu (jego pliki pozostały niezmienione) i stwierdziłem, że ich sumy md5 były różne. Zakładam, że w nagłówku tar znajduje się znacznik czasu, ale nie znalazłem sposobu, aby go zastąpić. Mój system operacyjny to Ubuntu 9.1. Jakieś pomysły ?

Dzięki.

Xain
źródło
Pokaż komendę tar, której używasz. Nie powinno być żadnej różnicy, chyba że pliki są modyfikowane. Nawet touch filenamektóra zmiana zmodyfikowanego czasu pliku wystarczy, aby zmienić sumę kontrolną.
Wstrzymano do odwołania.
Oto polecenie: tar czf one.tgz ./bin; tar czf two.tgz ./bin. Wtedy oba md5 są różne.
xain
To nie jest sam tar, wydaje się być gzip. Jeśli zamiast tego użyjesz j dla bzip2, daje to tę samą sumę md5. To może być błąd - wypróbowałem to na Cygwin i dostałem taką samą sumę kontrolną. (Mam również Ubuntu 9.10 i uzyskiwałem tam różne wyniki, tak jak ty.)
Wstrzymano do odwołania.

Odpowiedzi:

13

Jak wskazał Dennis powyżej, to gzip. Część nagłówka gzip to czas modyfikacji dla wszystkiego, co jest skompresowane w pliku. Jeśli potrzebujesz gzip, możesz skompresować plik tar jako dodatkowy krok poza tar, zamiast używać wewnętrznego gzip tar. Polecenie gzip ma flagę, która powstrzymuje oszczędzanie czasu modyfikacji.

tar -c ./bin |gzip -n >one.tgz
tar -c ./bin |gzip -n >two.tgz
md5sum one.tgz two.tgz

Nie wpłynie to na czasy wewnątrz pliku tar, tylko ten w nagłówku gzip.

Jeff Snider
źródło
4
Możliwe jest także przekazanie opcji gzip do tar jakGZIP=-n tar -cz ...
oseiskar
6

Aby utworzyć plik tar ze spójną sumą kontrolną, po prostu wstaw w GZIP=-nnastępujący sposób:

GZIP=-n tar -zcf myOutputTarball.tar /home/luke/directoryIWantToZip

Jak to działa: Tar może akceptować opcje gzip przy użyciu tymczasowej GZIPzmiennej środowiskowej, jak wyżej. Jak powiedział Valter, tar używa gzip, który domyślnie umieszcza znacznik czasu w archiwum. Oznacza to, że otrzymujesz inną sumę kontrolną podczas kompresji tych samych plików. Ta -nopcja wyłącza tę sygnaturę czasową.

Łukasz
źródło
4

Miałem też ten problem, aby gzip nie zmieniał znacznika czasu, użyj gzip -n

-n, --no-name nie zapisuje ani nie przywraca oryginalnej nazwy i znacznika czasu

[valter.silva@alog ~]$ gzip --help
Usage: gzip [OPTION]... [FILE]...
Compress or uncompress FILEs (by default, compress FILES in-place).

Mandatory arguments to long options are mandatory for short options too.

  -c, --stdout      write on standard output, keep original files unchanged
  -d, --decompress  decompress
  -f, --force       force overwrite of output file and compress links
  -h, --help        give this help
  -l, --list        list compressed file contents
  -L, --license     display software license
  -n, --no-name     do not save or restore the original name and time stamp
  -N, --name        save or restore the original name and time stamp
  -q, --quiet       suppress all warnings
  -r, --recursive   operate recursively on directories
  -S, --suffix=SUF  use suffix SUF on compressed files
  -t, --test        test compressed file integrity
  -v, --verbose     verbose mode
  -V, --version     display version number
  -1, --fast        compress faster
  -9, --best        compress better
    --rsyncable   Make rsync-friendly archive

With no FILE, or when FILE is -, read standard input.

Report bugs to <[email protected]>.

Przykład:

[valter.silva@alog ~]$ ls
renewClaroMMSCanaisSemanal.log.gz  s3

[valter.silva@alog ~]$ gunzip renew.log.gz 
[valter.silva@alog ~]$ gunzip s3/renew.log.gz 

[valter.silva@alog ~]$ md5sum renew.log 
d41d8cd98f00b204e9800998ecf8427e  renew.log

[valter.silva@alog ~]$ md5sum s3/renew.log 
d41d8cd98f00b204e9800998ecf8427e  s3/renew.log

[valter.silva@alog ~]$ gzip -n renew.log 
[valter.silva@alog ~]$ gzip -n s3/renew.log 

[valter.silva@alog ~]$ md5sum renew.log.gz 
7029066c27ac6f5ef18d660d5741979a  renew.log.gz

[valter.silva@alog ~]$ md5sum s3/renew.log.gz 
7029066c27ac6f5ef18d660d5741979a  s3/renew.log.gz
Valter Silva
źródło
0

Zaskoczyłem króliczą dziurę po tym, jak inne odpowiedzi zawiodły mnie, i udało mi się dowiedzieć, że moja wersja tar (1.27.1 z repozytorium OSS openSUSE 42.3) paxdomyślnie używa niedeterministycznego formatu archiwalnego, co oznacza, że ​​nawet bez kompresji (a nawet jawnego ustawienia mtime) archiwa utworzone przy pomocy tar z tych samych plików mogą się różnić:

$ echo hi > test.file
$ tar --create --to-stdout test.file # long form of `tar cO test.file`
./PaxHeaders.13067/test.file0000644000000000000000000000013213427447703012603 xustar0030 mtime=1549684675.835011178
30 atime=1549684726.410510251
30 ctime=1549684675.835011178
test.file0000644000175000001440000000000313427447703013057 0ustar00hartusers00000000000000hi
$ tar --create --to-stdout test.file
./PaxHeaders.13096/test.file0000644000000000000000000000013213427447703012605 xustar0030 mtime=1549684675.835011178
30 atime=1549684726.410510251
30 ctime=1549684675.835011178
test.file0000644000175000001440000000000313427447703013057 0ustar00hartusers00000000000000hi

Zauważ, że powyższe dane wyjściowe różnią się, mimo że nie jest używana żadna kompresja ; nieskompresowane treści archiwów (generowane przez dwukrotne uruchomienie tar na tej samej zawartości) są różne, więc skompresowana zawartość będzie się różnić, nawet gdy będzie używana, GZIP=-njak sugerują inne odpowiedzi

Aby obejść ten problem, możesz określić --format gnu :

$ tar --create --format gnu --to-stdout test.file
test.file0000644000175000001440000000000313427447703011557 0ustar  hartusershi
$ tar --create --format gnu --to-stdout test.file
test.file0000644000175000001440000000000313427447703011557 0ustar  hartusershi

Działa to z powyższą sugestią dotyczącą gzip:

# gzip refuses to write to stdout, so we'll use the `-f` option to create a file
$ GZIP=-n tar --format gnu -czf test.file.tgz test.file && md5sum test.file.tgz
0d8c7b3bdbe8066b516e3d3af60ade75  test.file.tgz
$ GZIP=-n tar --format gnu -czf test.file.tgz test.file && md5sum test.file.tgz
0d8c7b3bdbe8066b516e3d3af60ade75  test.file.tgz

# without GZIP=-n we see a different hash
$ tar --format gnu -czf test.file.tgz test.file && md5sum test.file.tgz
682ce0c8267b90f4103b4c29903c5a8d  test.file.tgz

Jednak oprócz uzasadnionych powodów preferowania lepszych formatów kompresji niż gzip , możesz rozważyć użycie zamiast tego xz (który tar obsługuje również z flagami --xzlub -Jzamiast -z), ponieważ oszczędza ci to kroku; domyślnym zachowaniem xzjest generowanie tego samego skompresowanego wyjścia, gdy nieskompresowana zawartość jest taka sama, więc nie ma potrzeby określania opcji takiej jak GZIP=-n:

$ tar --format gnu --xz -cf test.file.txz test.file && md5sum test.file.txz 
dea99037d4b0ee4565b3639e93ac0930  test.file.txz
$ tar --format gnu --xz -cf test.file.txz test.file && md5sum test.file.txz 
dea99037d4b0ee4565b3639e93ac0930  test.file.txz
Hart Simha
źródło