Bagaimana cara membandingkan bagian file dengan hash?


19

Saya punya satu file yang berhasil diunduh dan satu lagi unduhan gagal (hanya 100 MB pertama dari file besar) yang saya duga adalah file yang sama.

Untuk memverifikasi ini, saya ingin memeriksa hash mereka, tetapi karena saya hanya memiliki bagian dari file yang gagal diunduh, saya hanya ingin hash beberapa megabyte pertama atau lebih.

Bagaimana saya melakukan ini?

OS akan menjadi windows, tetapi saya telah menginstal cygwin dan MinGW.


1
Secara efisien membandingkan satu file di komputer lokal dengan file lain di komputer yang jauh adalah bagian kunci rsync , yang membandingkan bagian-bagian file dengan fungsi hash khusus.
David Cary

@ DavidCary Dalam kasus saya, saya tidak memiliki akses shell ke komputer jarak jauh, tapi terima kasih atas petunjuknya, saya akan membaca halaman manual
berdosa

Jawaban:


56

Membuat hash untuk membandingkan file masuk akal jika Anda membandingkan satu file dengan banyak file, atau ketika membandingkan banyak file satu sama lain.

Tidak masuk akal ketika membandingkan dua file hanya sekali: Upaya untuk menghitung hash setidaknya setinggi berjalan di atas file dan membandingkannya secara langsung.

Alat perbandingan file yang efisien adalah cmp:

cmp --bytes $((100 * 1024 * 1024)) file1 file2 && echo "File fragments are identical"

Anda juga dapat menggabungkannya dengan dduntuk membandingkan bagian acak (tidak harus dari awal) dari dua file, misalnya:

cmp \
    <(dd if=file1 bs=100M count=1 skip=1 2>/dev/null) \
    <(dd if=file2 bs=100M count=1 skip=1 2>/dev/null) \
&& echo "File fragments are identical"

6
Catatan: membuat hash untuk membandingkan file juga masuk akal jika Anda ingin menghindari membaca dua file sekaligus.
Kamil Maciorowski

1
@KamilMaciorowski Ya, benar. Tetapi metode ini biasanya masih lebih cepat daripada membandingkan hash dalam case berpasangan.
Konrad Rudolph

8
Ini adalah solusi yang harus dilakukan. cmpadalah 99,99% pasti sudah diinstal jika Anda sudah bashmenjalankan, dan itu berhasil. Memang, cmp -n 131072 one.zip two.zip akan melakukan pekerjaan itu juga. Karakter paling sedikit untuk diketik, dan eksekusi tercepat. Menghitung hash tidak masuk akal. Ini membutuhkan seluruh file 100MB untuk dibaca, ditambah porsi 100MB dari file lengkap, yang tidak ada gunanya. Jika mereka file zip dan mereka berbeda, akan ada perbedaan dalam beberapa ratus byte pertama. Readahead memberikan 128k secara default, jadi Anda juga dapat membandingkan 128k (biaya yang sama dengan membandingkan 1 byte).
Damon

19
The --bytesopsi hanya rumit tugas. Jalankan saja cmptanpa opsi ini dan itu akan menampilkan byte pertama yang berbeda antara file. Jika semua byte sama maka akan ditampilkan EOFpada file yang lebih pendek. Ini akan memberi Anda lebih banyak informasi daripada contoh Anda - berapa banyak byte yang benar.
pabouk

2
Jika Anda memiliki GNU cmp(dan, saya pikir hampir semua orang memiliki GNU ), Anda dapat menggunakan --ignore-initialdan --bytesberargumentasi alih-alih mempersulit hal dengan doa dd.
Christopher Schultz

12

Maaf saya tidak bisa mencobanya, tapi cara ini akan berhasil

dd if=yourfile.zip of=first100mb1.dat bs=100M count=1
dd if=yourotherfile.zip of=first100mb2.dat bs=100M count=1

Ini akan memberi Anda 100 Megabyte pertama dari kedua file.

Sekarang ambil hash:

sha256sum first100mb1.dat && sha256sum first100mb2.dat 

Anda juga dapat menjalankannya secara langsung:

dd if=yourfile.zip bs=100M count=1 | sha256sum 
dd if=yourotherfile.zip bs=100M count=1 | sha256sum 

1
Apakah ada cara untuk pipa dd entah bagaimana ke sha256sum tanpa file perantara?
berdosa

1
Saya menambahkan cara lain sesuai permintaan Anda
davidbaumann

8
Mengapa membuat hash? Itu jauh lebih efisien daripada hanya membandingkan fragmen file secara langsung (menggunakan cmp).
Konrad Rudolph

Dalam contoh kode tengah Anda, Anda mengatakan first100mb1.dat dua kali. Apakah maksud Anda first100mb 2 .dat untuk yang kedua?
doppelgreener

@KonradRudolph, "Mengapa membuat hash?" Solusi Anda (menggunakan cmp) adalah pemenang tanpa keraguan. Tetapi cara memecahkan masalah ini (menggunakan hash) juga memiliki hak untuk ada selama itu benar-benar menyelesaikan masalah (:
VL-80

7

Semua orang tampaknya menggunakan rute Unix / Linux dengan ini, tetapi hanya membandingkan 2 file dapat dengan mudah dilakukan dengan perintah standar Windows:
FC /B file file2

FC hadir di setiap versi Windows NT yang pernah dibuat. Dan (jika saya ingat dengan benar) juga hadir di DOS.
Agak lambat, tapi itu tidak masalah untuk sekali pakai.


6

Anda bisa langsung membandingkan file, dengan program biner / hex seperti vbindiff. Dengan cepat membandingkan file hingga 4GB di Linux & Windows.

Terlihat seperti ini, hanya dengan perbedaan yang disorot dalam warna merah (1B vs 1C):

one                                       
0000 0000: 30 5C 72 A7 1B 6D FB FC  08 00 00 00 00 00 00 00  0\r..m.. ........  
0000 0010: 00 00 00 00                                       ....
0000 0020:
0000 0030:
0000 0040:
0000 0050:
0000 0060:
0000 0070:
0000 0080: 
0000 0090: 
0000 00A0: 

two        
0000 0000: 30 5C 72 A7 1C 6D FB FC  08 00 00 00 00 00 00 00  0\r..m.. ........  
0000 0010: 00 00 00 00                                       ....               
0000 0020: 
0000 0030:
0000 0040:
0000 0050:
0000 0060:
0000 0070:
0000 0080:
0000 0090:                                
0000 00A0:             
┌──────────────────────────────────────────────────────────────────────────────┐
Arrow keys move  F find      RET next difference  ESC quit  T move top        
C ASCII/EBCDIC   E edit file   G goto position      Q quit  B move bottom     
└──────────────────────────────────────────────────────────────────────────────┘ 

Dalam kasus saya, file-file tersebut adalah arsip zip, jadi tidak ada teks yang bermakna di sana. Membandingkan nilai hash harus lebih cepat dan lebih sedikit kesalahan.
berdosa

2
Jika Anda maksud teks ASCII, maka itu tidak relevan. vbindiff(dan Konrad cmp) membandingkan data biner, byte untuk byte. Bahkan memiliki nilai jauh lebih mungkin mengalami tabrakan
Xen2050

* Dimaksudkan "Sebenarnya nilai HASH jauh lebih mungkin untuk mengalami tabrakan" dalam komentar di atas, ketinggalan h!
Xen2050

0

Saya tahu dikatakan untuk Bash, tetapi OP juga menyatakan bahwa mereka memiliki Windows. Bagi siapa pun yang menginginkan / memerlukan solusi Windows, ada program yang disebut HxD yang merupakan Hex Editor yang dapat membandingkan dua file. Jika ukuran file berbeda, itu akan memberi tahu apakah bagian yang tersedia adalah sama. Dan jika perlu, itu mampu menjalankan checksum untuk apa pun yang saat ini dipilih. Gratis dan dapat diunduh dari: situs web HxD . Saya tidak memiliki koneksi ke penulis, saya baru saja menggunakannya selama bertahun-tahun.


0

cmp akan memberi tahu Anda ketika dua file identik hingga panjang file yang lebih kecil:

$ dd if=/dev/random bs=8192 count=8192 > a
8192+0 records in
8192+0 records out
67108864 bytes transferred in 0.514571 secs (130417197 bytes/sec)
$ cp a b
$ dd if=/dev/random bs=8192 count=8192 >> b 
8192+0 records in
8192+0 records out
67108864 bytes transferred in 0.512228 secs (131013601 bytes/sec)
$ cmp a b
cmp: EOF on a

cmp memberi tahu Anda bahwa perbandingan menemukan EOF pada file a sebelum mendeteksi perbedaan antara kedua file.


Poin bagus. Jika Anda belum melihatnya, ini adalah pabouk yang sudah mengomentari jawaban yang diterima.
berdosa
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.