コピーされたファイルが元のファイルと同一であるかどうかを確認するために、すべての単一バイトを読み取る必要がありますか?


16

最近、Total Commanderというプログラムを知りました。これはWindows Explorerの代替品であり、ファイルをコピーするための独自のものがあります。ファイルが同一であるかどうかをチェックするために、CRCを計算する代わりに、オリジナルとコピーの両方で1バイトずつ文字通りチェックします。

私の質問は:これは必要ですか?CRCや他のそのような技術はうまくいかないのでしょうか?あなたは、プログラマーとして、この完璧であるが遅いシステムを試して実装すべきでしょうか、それとも極端すぎますか?


3
「rsync」がこれをどのように処理するかを見てください。

21
両方のファイルでCRC(または、より良いことにsha1sums)を計算するには、とにかくすべてのバイトを読み取る必要があります。バイトごとの比較を行う場合、不一致が見られたらすぐに終了できます-同じチェックサムを持つ2つの異なるファイルを心配する必要はありません(sha1sumではほとんどありそうにありませんが) 。一方、チェックサム比較は、同じマシン上にないファイルを比較するときに役立ちます。チェックサムはローカルで計算でき、コンテンツ全体をネットワーク経由で転送する必要はありません。
キーストンプソン

3
衝突の可能性に関してsha1sumは、sha1sumが衝突するファイルを誰かが意図的かつ高価に作成しない限り、まともなハッシュを使用すれば、ほとんど心配する必要はありません。このソースはありませんが、2つの異なるファイルが同じsha1sumを持っている確率は、開発チームのすべてのメンバーが食べられる確率とほぼ同じであると(gitのコンテキストで)聞いたことがありますオオカミ。同じ日に。まったく関係のない事件。
キーストンプソン

5
@KeithThompson:最初のコメントは答えになるはずだと思う:
ディーンハーディング

6
簡単な答え-いいえ、あなたのコンピューターにあなたのためにそれをしてもらうことが最善です。
psr

回答:


40

両方のファイルでCRC(または、より良いことにsha1sums)を計算するには、とにかくすべてのバイトを読み取る必要があります。バイトごとの比較を行う場合、不一致が見られたらすぐに終了できます-同じチェックサムを持つ2つの異なるファイルを心配する必要はありません(sha1sumではほとんどありそうにありませんが) 。したがって、ローカルで比較を行う場合、バイト単位の比較は、少なくともチェックサム比較と同じくらい高速になります(とにかくチェックサムを既に計算していない限り)。

一方、チェックサム比較は、同じマシン上にないファイルを比較するときに役立ちます。チェックサムはローカルで計算でき、コンテンツ全体をネットワーク経由で転送する必要はありません。

ハイブリッドアプローチも可能です。たとえば、計算し、(全体のファイルを読み込むことができないよう一度に2つのファイルチャンクのためのチェックサムの比較可能性があるならば、彼らは異なる)も、ネットワーク経由でファイル全体を送信回避しながらの。rsyncのプロトコルは、このような何かを行います。

Dave Ragerが答えで述べたように、単純なCRCを使用すると、衝突の可能性がかなり高くなることに注意してください。少なくとも sha1sum、またはそれより新しいものを使用ます。(独自のハッシュアルゴリズムを発明しようとしないでください。sha1sumを開発した人々は、私たちよりもはるかにこのことについてよく知っています。)

あなたがSHA1SUMのようなまともなハッシュを使用している場合、誰かが意図的とされていない限り、衝突の可能性として、あなたはかなり、それを心配する必要はありません費用をかけてそのsha1sums衝突(このような衝突が発生したファイルを構築可能ではない、私が最初にこれを書いたときに、しかし進歩はなされている)。引用スコット・チャコンの「プロのGit」セクション6.1

これは、SHA-1コリジョンを起こすために必要なことを理解するための例です。地球上の65億人すべてがプログラミングを行い、1秒ごとに、Linuxカーネルの歴史全体(100万Gitオブジェクト)に相当するコードを作成し、それを1つの巨大なGitリポジトリにプッシュすると、5年かかりますそのリポジトリには、単一のSHA-1オブジェクトの衝突の確率が50%になるのに十分なオブジェクトが含まれていました。プログラミングチームのすべてのメンバーが、同じ夜に無関係なインシデントでオオカミに攻撃されて殺される可能性が高くなります。

まとめ:

バイトごとの比較は、ローカル比較に適しています。sha1sumはリモート比較に適していて、誤検知の重大な可能性はありません。


「良い」ハッシュ関数の一般的な定義には、同じハッシュで異なる入力を作成するのが非常に難しいという特性が含まれていることに注意してください(「衝突抵抗」)。SHA-1には、この点で(これまでの理論上の)弱点がいくつかありますが、かなり一生懸命試してみても、「衝突する2つのファイルを構築する」ことはできません。
sleske

@sleske:更新
キーストンプソン

1
@KeithThompson私は答えを支持していますが、SHA1- The SHAppening
K.Steffの

この理論上のリポジトリをGitHubでホストしようとすると、彼らは不機嫌になると思います。
hBy2Py

1
私は、彼らが毎秒何エクサバイトものデータを送信することに不満を持っていることを意味していました。:-)
hBy2Py

10

これについて考える別の方法があります。

2つの異なるファイルが同じCRCを持つ可能性がない場合、拡張により、すべてのファイルを一意のCRCで表すことができることを意味します。CRCが元のファイルよりも小さかった場合、可逆圧縮の形式を表します。そうでない場合は、同じバイト数を比較するため、元のファイルを比較することもできます。

理論的には、比較の両側のロスレス圧縮を使用して比較に必要なバイト数を減らすことができますが、圧縮を行うにはより多くのサイクルを無駄にし、両方のファイルのすべてのバイトを読み取る必要があるため、バカ使いです。つまり、ロスレス圧縮方式ですべてのバイト(およびその順序)をエンコードするには、最初にそれを読み込んでアルゴリズムにプラグインする必要があります。ゲームオーバー。

ここにアナロジーがあります:
あなたはすぐに2つのプリント文書は文字で文字を比較することなく、同一であったかどうかを判断するための方法を望んでいた場合は、文書の各ライン上の文字の数を比較することができます。カウントがすべて一致した場合、ドキュメントが同一である確率は大幅に向上しますが、このアプローチを使用してすべての文字が同じであると確信できると主張する人はいません。


3

同一ファイルをチェックする唯一の完璧な方法は、バイト比較のためのバイトです。公正な近似となるもう1つの方法は、ファイルのMD5などのハッシュを計算し、それらを比較することです。ハッシュ衝突が発生する可能性はありますが、そうなる可能性は低いです。

バイト比較のバイトは、比較を行うときに両方のファイルでハッシュを計算するよりも高速になると思います。ただし、アプリケーションがハッシュを事前に計算し、ファイルに関するメタデータを保存している場合、ハッシュの比較は非常に高速になります。

CRCは、ハッシュではなく単なるエラー検出メカニズムであるため、おそらく移動する方法ではありません。(または、多くの衝突の可能性がある貧弱なハッシュ)


+1同意します。適切なハッシュ関数の偶発的な衝突と比較して、ハードドライブが破損する可能性が非常に高くなります(CRC32は脆弱です-また同意します)。
ミチャウシュラージェル

2

2つのファイルが同一であることを100%特定するには、実際にバイトをチェックする必要があります。

どうして?ハッシュ衝突、それが理由です!ハッシュに使用されるアルゴリズムに応じて、衝突の可能性は多少なりますが、それでも可能性はあります。以下の手順に従います。

  1. ファイルサイズを確認する
  2. MIMEタイプを確認する
  3. ハッシュをチェック
  4. いくつかのランダムなオフセットを確認し、ビットを比較します

2つのファイルが同じであることを非常に高い確実性で保証しますが、手に衝突する可能性は非常に(非常に)わずかです。あなたがあなたの比較をどこまでやりたいかの選択は、状況によって決まります。


適切なハッシュアルゴリズムを選択した場合、2。と4.は「同等の」品質を実際に向上させることはありません。おそらく1.は弱いハッシュに対しても同様に必要です。
ミチャウシュラージェル

1
-1これは意味がありません。適切なハッシュアルゴリズムを選択した場合、他のすべての手順は不要です。1.と4.は実際にハッシュの機能ですでにカバーされています。2。はナンセンスです(ほとんどのファイルシステムには「MIMEタイプ」という概念さえありません。
sleske

@sleske集中的な操作であるファイルのハッシュを一掃する代わりに、それほど重くない予備的な操作を実行できると言っています。

私は1と3だけを調整します。(1)異なるファイルのほとんどの場合にフラグを立て、ハッシュを計算する必要を省きます。同じ長さのファイルでのハッシュの衝突は、それほど心配する価値はありません。
マイケルショー

1

他の人が言ったように、2つのファイルが同じシステム上にある場合、バイトごとの比較を行う方が高速です。多数のファイルを比較しようとする場合、ファイルが回転するストレージ上にある場合、ハッシュがより良い答えになる点に到達します。

ハッシュは、すべてのデータをすぐに入手できるわけではない場合に、本当に光ります。たとえば、ファイルは異なるマシン上にあります。また、計算結果を保存して、後で参照することもできます。(このレポートは古いレポートと同じですか?レポートを作成すると、そのハッシュを保存します。次のレポートを作成すると、単にハッシュを比較できます。古いレポートを読む必要がないだけではありません。」コピーを入手する必要さえありません。)


0

提供されているファイル比較ユーティリティをオペレーティングシステムで使用するか、ファイル比較ツール(wikiファイル比較ツールを参照)を使用して、@ Glenn Nelsonが概説したファイルプロパティを確認した後に内容を比較する必要があると思います。

CRCが100%正確であるとは思わず、ファイルの長さとともにその精度が低下すると思います。また、多くのテストが必要になる可能性があるため、ゼロから作成することはお勧めしません。


0

コピーされたファイルが元のファイルと同一であるかどうかを確認するために、すべての単一バイトを読み取る必要がありますか?はい、100%確信しています

コピーされたファイルが元のファイルと同一ではないかどうかを確認するために、すべての単一バイトを読み取る必要がありますか?番号

したがって、非同一性を迅速に判断するには、まずファイルサイズや、OS / file-system / storeがすでに維持している可能性のあるチェックサム/ CRCまたはMIMEタイプなどのメタデータを確認します。それらはそのシステムによって事前に計算されているため、比較時にこの費用を支払うことはありません。

そのテストに合格した場合でも、100%確実である必要がある場合は、すべてのバイトを個別に比較する必要がありますが、最新のパイプラインCPUでは、複数のスレッドと場合によっては複数のプロセッサ/ CPUを使用して、大きなファイルのブロック比較が非常に高速であることに注意してくださいプロセスは高度に並列化可能であるため効率的。各バイトを含むあらゆる種類の数学的計算よりもはるかに高速です(ただし、一部のアルゴリズムは並列化も可能ですが、おそらくそれほど簡単ではありません)。これは、パイプライン化されたCPUがマイクロコードまたはハードウェア(非常に高速)でメモリのブロック比較操作を実行でき、ディスクからメモリのサブシステムが非常に最適化され、メモリとの間でファイルの巨大なブロックをすべて並行して、ハードウェア。アプリケーションがこの種のことを定期的に行い、既知のパフォーマンスのボトルネックである場合、OSおよびハードウェアの並列化機能を利用する適切に記述されたマルチスレッドコードでこれを実装するのが賢明です(おそらく、この)。

各ファイルを1回処理し、後で複数の比較を実行する場合のみ(「キャッシュ」で要約された、または「圧縮」(JohnFXが言うように)分析結果を覚えている場合)そして、それでも、違いを証明するためだけに(おそらく); 同一性を証明するには、バイト単位の比較を行う必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.