Dosya parçalarını karma ile nasıl karşılaştırırım?


19

Bir dosya başarıyla yüklendi ve aynı dosya olduğundan şüphelendiğim başka bir başarısız indirme (sadece büyük bir dosyanın ilk 100 MB) var.

Bunu doğrulamak için, karmaları kontrol etmek istiyorum, ancak başarısız bir şekilde indirilen dosyanın sadece bir kısmına sahip olduğum için, sadece ilk birkaç megabayt hash etmek istiyorum.

Bunu nasıl yaparım?

İşletim sistemi pencereler olurdu, ancak cygwin ve MinGW yüklü.


1
Yerel bir bilgisayardaki bir dosyayı uzaktaki bir bilgisayardaki başka bir dosyayla verimli bir şekilde karşılaştırmak , dosyaların parçalarını özel bir karma işleviyle karşılaştıran rsync'in önemli bir parçasıdır .
David Cary

@DavidCary Benim durumumda, uzak bilgisayara kabuk erişimim yok, ancak ipucu için teşekkürler, manpage'i okuyacağım
günah

Yanıtlar:


56

Dosyaları karşılaştırmak için karmaları oluşturmak, bir dosyayı birçok dosyayla karşılaştırdığınızda veya birçok dosyayı birbiriyle karşılaştırdığınızda mantıklıdır.

İki dosyayı yalnızca bir kez karşılaştırmak mantıklı değildir: Karmaları hesaplama çabası, en azından dosyaların üzerinde yürümek ve doğrudan karşılaştırmak kadar yüksektir.

Verimli bir dosya karşılaştırma aracı cmp:

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

Ayrıca dd, iki dosyanın rastgele bölümlerini (başlangıçtan itibaren olması gerekmez) karşılaştırmak için birleştirebilirsiniz , örneğin:

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
Not: İki dosyayı aynı anda okumaktan kaçınmak istiyorsanız, dosyaları karşılaştırmak için karma oluşturmak da mantıklıdır.
Kamil Maciorowski

1
@KamilMaciorowski Evet, doğru. Ancak bu yöntem genellikle ikili durumda karmaları karşılaştırmaktan daha hızlı olacaktır.
Konrad Rudolph

8
Bu çözümdür. cmpçalışıyorsa% 99,99 önceden kurulmuş olduğundan emin olun bashve işi yapar. Gerçekten de cmp -n 131072 one.zip two.zip bu işi yapacak. Yazması gereken en az karakter ve en hızlı yürütme. Bir karma hesaplamak saçmadır. Tüm 100MB dosyasının okunmasını ve ayrıca dosyanın tamamının 100MB bölümünü anlamsız kılar . Zip dosyalarıysa ve farklılarsa, ilk birkaç yüz bayt arasında bir fark olacaktır. Readahead varsayılan olarak 128k sunar, böylece 128k'yi de karşılaştırabilirsiniz (1 bayt karşılaştırmasıyla aynı maliyet).
Damon

19
--bytesSeçenek yalnızca görevi ağırlaştırmaktadır. Sadece cmpbu seçenek olmadan çalıştırın ve dosyalar arasında farklılık gösteren ilk baytı gösterecektir. Tüm baytlar aynıysa EOF, daha kısa dosyada gösterilir. Bu, örneğinizden daha fazla bilgi verecektir - kaç bayt doğrudur.
pabouk

2
GNU'yu varsa cmp, kullanabilirsiniz (ve, hemen hemen herkesin gelmez düşünüyorum) --ignore-initialve --bytesyerine çağrımı ile durumu karıştırma gibi argümanlar dd.
Christopher Schultz

12

Üzgünüm, bunu tam olarak deneyemiyorum, ama bu şekilde çalışacak

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

Bu size her iki dosyanın ilk 100 Megabaytını verecektir.

Şimdi karmaları alın:

sha256sum first100mb1.dat && sha256sum first100mb2.dat 

Ayrıca doğrudan çalıştırabilirsiniz:

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

1
Dd ara dosya olmadan bir şekilde sha256sum içine boru bir yolu var mı?
günah işlemiş

1
İsteğinize göre başka bir yol ekledim
Davidbaumann

8
Neden karmaları yaratmalıyım? Bu sadece dosya parçalarını doğrudan karşılaştırmaktan çok daha az verimlidir cmp.
Konrad Rudolph

Orta kod örneğinizde iki kez first100mb1.dat diyorsunuz. Bunu mu demek istediniz: first100mb 2 .dat ikincisi için?
doppelgreener

@KonradRudolph, "Neden karmaları yaratmalıyım?" Çözümünüz (kullanma cmp) şüphesiz bir kazanandır. Ancak sorunu çözmenin bu yolu (karma kullanarak), sorunu gerçekten çözdüğü sürece de var olma hakkına sahiptir (:
VL-80 0

7

Herkes bununla Unix / Linux yoluna gidiyor gibi görünüyor, ancak sadece 2 dosyayı karşılaştırmak Windows standart komutlarıyla kolayca yapılabilir:
FC /B file file2

FC şimdiye kadar yapılmış her Windows NT sürümünde mevcuttur. Ve (doğru hatırlıyorsam) DOS da mevcuttu.
Biraz yavaş, ama bir kerelik kullanım için önemli değil.


6

Sadece doğrudan bir ikili / hex diff programı ile dosyaları karşılaştırabilirsiniz vbindiff. Linux ve Windows'da 4 GB'a kadar olan dosyaları hızla karşılaştırır.

Sadece kırmızı renkte vurgulanan farkla (1B vs 1C) böyle bir şey görünüyor:

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     
└──────────────────────────────────────────────────────────────────────────────┘ 

Benim durumumda, dosyalar zip arşivleridir, bu yüzden orada anlamlı bir metin yoktur. Hash değerini karşılaştırmak daha hızlı ve daha az hataya açık olmalıdır.
günah işledi

2
ASCII metnini kastediyorsanız, bu önemsizdir. vbindiff(ve Konrad's cmp) ikili verileri bayt için bayt karşılaştırır. Aslında değerlerin çarpışma yaşama olasılığı daha yüksektir
Xen2050

* Yukarıdaki yorumda " Aslında HASH değerleri çarpışma yaşama olasılığı çok daha fazla" anlamına geliyordu, h kaçırdı!
Xen2050

0

Bash için yazdığını biliyorum, ama OP ayrıca Windows'a sahip olduklarını da belirtiyor. Windows çözümü isteyen / gerektiren herkes için, iki dosyayı karşılaştırabilen bir Hex Editor olan HxD adlı bir program var. Dosyalar farklı boyutlarda ise, mevcut parçaların aynı olup olmadığını söyleyecektir. Ve gerekirse, şu anda seçili olanlar için sağlama toplamları çalıştırabilir. Ücretsizdir ve HxD web sitesinden indirilebilir . Yazarlarla hiçbir bağlantım yok, sadece yıllardır kullanıyorum.


0

cmp, iki dosya daha küçük dosyanın uzunluğuna eşit olduğunda size bildirir:

$ 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, karşılaştırmanın iki dosya arasında herhangi bir fark tespit etmeden önce a dosyasında bir EOF ile karşılaştığını söylüyor.


İyi bir nokta. Eğer görmediyseniz, pabouk'un kabul edilen cevaba zaten yorum yaptığı şey budur.
günah işledi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.