ハッシュでファイルの部分を比較する方法は?


19

1つのファイルが正常にダウンロードされ、別のダウンロードが失敗しました(大きなファイルの最初の100 MBのみ)。同じファイルであると思われます。

これを確認するために、ハッシュをチェックしたいと思いますが、ダウンロードに失敗したファイルの一部しか持っていないため、最初の数メガバイト程度をハッシュしたいだけです。

どうすればいいですか?

OSはWindowsですが、cygwinとMinGWがインストールされています。


1
ローカルコンピューター上の1つのファイルと離れたコンピューター上の別のファイルを効率的に比較することは、ファイルの一部を特別なハッシュ関数と比較するrsyncの重要な部分です。
デビッドケーリー

私の場合は@DavidCaryは、私は、リモートコンピューターへのシェルアクセスを持っていないが、ヒントのおかげで、私は、manページを読み込みます
罪を犯した

回答:


56

ハッシュを作成してファイルを比較することは、1つのファイルを多数と比較する場合、または多数のファイルを相互に比較する場合に意味があります。

2つのファイルを一度だけ比較する場合は意味がありません。ハッシュを計算する労力は、少なくともファイルを調べて直接比較するのと同じくらい高くなります。

効率的なファイル比較ツールはcmp次のとおりです。

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

またdd、2つのファイルの任意の部分(必ずしも最初からではない)を比較するためにそれを組み合わせることができます。例えば:

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
注:ファイルを比較するハッシュを作成することは、同時に2つのファイルを読み取らないようにする場合にも意味があります。
カミルマシオロウスキ

1
@KamilMaciorowskiはい、本当です。ただし、この方法は通常、ペアワイズの場合にハッシュを比較するよりも高速です。
コンラッドルドルフ

8
これは、解決策です。実行しcmpている場合、すでにインストールされていることが99.99%確実bashであり、ジョブを実行します。確かに、cmp -n 131072 one.zip two.zip 仕事もします。入力する文字数が少なく、実行速度が最速です。ハッシュの計算は無意味です。100MBのファイル全体を読み取る必要があり、さらに完全なファイルの100MBの部分が必要です。これは無意味です。それらがzipファイルであり、異なる場合、最初の数百バイト以内に違いがあります。ただし、Readaheadはデフォルトで128kを配信するため、128kを比較することもできます(1バイトの比較と同じコスト)。
デイモン

19
この--bytesオプションは、タスクを複雑にしているだけです。cmpこのオプションなしで実行すると、ファイル間で異なる最初のバイトが表示されます。すべてのバイトが同じ場合EOF、短いファイルに表示されます。これにより、例よりも多くの情報(正確なバイト数)が得られます。
パブーク

2
GNUをお持ちの場合cmp(そして、ほとんどの人がそうだと思います)、の呼び出しで物事を複雑にする代わりに--ignore-initialand --bytes引数を使用できますdd
クリストファーシュルツ

12

私はそれを正確に試すことはできませんが、この方法はうまくいきます

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

これにより、両方のファイルの最初の100メガバイトが取得されます。

ハッシュを取得します。

sha256sum first100mb1.dat && sha256sum first100mb2.dat 

直接実行することもできます:

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

1
中間ファイルなしでddをsha256sumにパイプする方法はありますか?
罪を犯した

1
私はあなたの要求に応じて別の方法を追加
davidbaumann

8
ハッシュを作成する理由 これは、ファイルフラグメントを直接比較するよりもはるかに効率的ではありません(を使用cmp)。
コンラッドルドルフ

中間のコードサンプルでは、​​first100mb1.datを2回言います。2番目の場合はfirst100mb 2 .dat を意味しましたか?
doppelgreener

@KonradRudolph、「ハッシュを作成する理由」あなたのソリューション(を使用cmp)は間違いなく勝者です。しかし、(ハッシュを使用して)問題を解決するためのこの方法はまた、限り、それは実際に(問題を解決として存在する権利を有する:
VL-80

7

誰もがこれでUnix / Linuxルートに行くようですが、Windowsの標準コマンドで2つのファイルを比較するだけで簡単に実行できます。
FC /B file file2

FCは、これまでに作成されたすべてのWindows NTバージョンに存在します。そして(もし正しく思い出せば)DOSにも存在していました。
それは少し遅いですが、それは一度限りの使用には関係ありません。


6

のようなバイナリ/ hex diffプログラムを使用して、ファイルを直接比較することができますvbindiff。LinuxとWindowsで最大4GBのファイルをすばやく比較します。

このように見えますが、違いは赤で強調表示されています(1B対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     
└──────────────────────────────────────────────────────────────────────────────┘ 

私の場合、ファイルはzipアーカイブなので、そこに意味のあるテキストはありません。ハッシュ値を比較すると、より高速でエラーが発生しにくくなります。
罪を犯した

2
ASCIIテキストを意味する場合、それは無関係です。vbindiff(およびKonradのcmp)は、バイナリデータをバイトごとに比較します。実際の値は、はるかに可能性の高い経験の衝突にありました
Xen2050

* 上記のコメントの「実際にはHASH値は衝突を経験する可能性がはるかに高い」という意味で、hを逃しました!
Xen2050

0

Bashのことを言っているのは知っていますが、OPにはWindowsがあると書かれています。Windowsソリューションを必要とする/必要とする人のために、2つのファイルを比較できる16進エディタであるHxDというプログラムがあります。ファイルのサイズが異なる場合、使用可能なパーツが同じかどうかがわかります。また、必要に応じて、現在選択されているものすべてのチェックサムを実行できます。無料で、HxD Webサイトからダウンロードできます。私は著者とは何の関係もありません。何年も使用しています。


0

cmpは、小さいファイルの長さまで2つのファイルが同一である場合に通知します。

$ 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は、2つのファイル間の違いを検出する前に、比較によりファイルaでEOFが発生したことを示しています。


いい視点ね。あなたがそれを見なかったなら、これはpaboukがすでに受け入れられた答えについてコメントしたものです。
罪を犯した
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.