Md5sums berbeda untuk konten tar yang sama

15

Saya menjalankan tes membuat dua tars dari dir yang sama (file-nya tetap tidak berubah), dan saya menemukan bahwa md5sums mereka berbeda. Saya berasumsi ada beberapa cap waktu yang dimasukkan dalam header tar, tapi saya belum menemukan cara untuk menimpanya. OS saya adalah Ubuntu 9.1. Ada ide?

Terima kasih.

tetap
sumber
Tampilkan baris perintah tar yang Anda gunakan. Seharusnya tidak ada perbedaan kecuali file sedang dimodifikasi. Bahkan touch filenameyang mengubah waktu file yang diubah sudah cukup untuk mengubah checksum.
Dijeda sampai pemberitahuan lebih lanjut.
Inilah perintahnya: tar czf one.tgz ./bin; tar czf two.tgz ./bin .Kemudian kedua md5 berbeda.
xain
Ini bukan tar itu sendiri, sepertinya gzip. Jika Anda menggunakan j untuk bzip2 sebagai gantinya, ia memberikan md5sum yang sama. Mungkin bug - Saya mencobanya di Cygwin dan mendapat checksum yang sama. (Saya memiliki Ubuntu 9,10 juga, dan telah mendapatkan hasil yang berbeda di sana, sama seperti Anda.)
Dijeda sampai pemberitahuan lebih lanjut.

Jawaban:

13

Seperti yang ditunjukkan Dennis di atas, ini gzip. Bagian dari header gzip adalah waktu mod untuk apa pun yang dikompres dalam file. Jika Anda membutuhkan gzip, Anda dapat mengompres tarfile sebagai langkah ekstra di luar tar daripada menggunakan gzip internal tar. Perintah gzip memiliki bendera untuk menekan penghematan waktu modifikasi itu.

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

Ini tidak akan mempengaruhi waktu di dalam tarfile, hanya yang ada di header gzip.

Jeff Snider
sumber
4
Dimungkinkan juga untuk memberikan opsi gzip ke tar sepertiGZIP=-n tar -cz ...
oseiskar
6

Untuk membuat file tar dengan checksum yang konsisten, cukup tambahkan sebelumnya GZIP=-nseperti ini:

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

Cara kerjanya: Tar dapat menerima opsi gzip menggunakan GZIPvariabel lingkungan sementara , seperti di atas. Seperti kata Valter, tar menggunakan gzip, yang secara default menempatkan timestamp di arsip. Ini berarti Anda mendapatkan checksum yang berbeda ketika Anda mengompres file yang sama. The -npilihan menonaktifkan timestamp itu.

Luke
sumber
4

Saya punya masalah ini juga, untuk membuat gzip tidak mengubah timestamp, gunakan gzip -n

-n, --no-name tidak menyimpan atau mengembalikan nama asli dan cap waktu

[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]>.

Contoh:

[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
sumber
0

Saya pergi ke lubang kelinci setelah jawaban yang lain gagal, dan berhasil mengetahui bahwa versi tar saya (1.27.1 dari repo openSUSE 42.3 OSS) menggunakan paxformat arsip non-deterministik secara default, yang berarti bahwa bahkan tanpa kompresi, (dan bahkan mengatur mtime secara eksplisit) arsip yang dibuat dengan tar dari file yang sama akan berbeda:

$ 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

Perhatikan bahwa output di atas berbeda, meskipun tidak ada kompresi yang digunakan ; konten arsip yang tidak dikompres (dihasilkan dengan menjalankan tar dua kali pada konten yang sama) berbeda, sehingga konten yang dikompresi juga akan berbeda bahkan ketika menggunakan GZIP=-nseperti jawaban lain menyarankan

Untuk menyiasatinya, Anda dapat menentukan --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

Ini berfungsi dengan saran tentang gzip di atas:

# 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

Namun, selain alasan yang sah untuk lebih memilih format kompresi yang lebih baik daripada gzip , Anda mungkin ingin mempertimbangkan untuk menggunakan xz sebagai gantinya (yang tar juga mendukung dengan --xzatau -Jtanda bukannya -z), karena itu menghemat langkah Anda di sini; perilaku default xzadalah untuk menghasilkan output terkompresi yang sama ketika konten terkompresi adalah sama, sehingga tidak perlu menentukan opsi seperti 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
sumber