2011-01-19 29 views
1

私が現在取り組んでいるC#プロジェクトでは、ネットワーク上の大量のファイルのMD5を計算しようとしています(現在のポットは270万、クライアントポットは1000万を超える)。私たちが処理しているファイルの数が増えれば、スピードが問題になります。C#ネットワーク上の高速MD5/SHAハッシュ

これを行う理由は、ファイルを変更せずに別の場所にコピーしたことを確認するためです。

我々は現在、ファイルが

MD5 md5 = new MD5CryptoServiceProvider(); 
StringBuilder sb = new StringBuilder(); 

byte[] hashMD5 = null; 

try 
{ 
    // Open stream to file to get MD5 hash for, create hash 
    using (FileStream fsMD5 = new FileStream(sFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
     hashMD5 = md5.ComputeHash(fsMD5); 
} 
catch (Exception ex) 
{ 
    clsLogging.logError(clsLogging.ErrorLevel.ERROR, ex); 
} 

string md5sum = ""; 
if (hashMD5 != null) 
{ 
    // Change hash into readable text 
    foreach (byte hex in hashMD5) 
     sb.Append(hex.ToString("x2")); 
    md5sum = sb.ToString(); 
} 

のMD5を計算するには、次のコードを使用し、この速度は、私のマネージャーが望んされたものではありません。私たちは、MD5を計算するファイルの方法と数にいくつかの変更を加えました(つまり、私たちがコピーしていないファイルに対しては行いません。 ALLファイルは、クライアントが、私はネットワークの速度がおそらく主要であることを認識

私は推測するので、すべてのファイルがコピーされ、私たちのプログラム)で時間を浪費することを希望するいくつかの将来の時点でのケースでそれらのために計算MD5を、持っている必要があります寄与因子(100Mbit/s)です。ネットワークを介してファイルの内容のMD5を計算する効率的な方法はありますか?

ありがとうございます。 Trevor Watson

編集:すべてのコードをその一部の代わりにブロックに入れます。

+0

ファイルがコピーされたマシン上でハッシュをローカルで確認できない理由はありますか? – arootbeer

+0

最初のビジネスポイントは、ボトルネックを把握することです。任意のベンチマークを実行して、ハッシュを計算せずにプロセスがファイルを読み込んで反復処理するのにかかる速さを確認しましたか?その後、ハッシュで;どのくらいのオーバーヘッドが計算を取っていますか?ローカルで同じタスクを実行しましたか? –

+0

私はAaronに同意します:ハッシュを計算するのに必要な時間は、ネットワーク上でリモートファイルを開き、ドライブの先頭に移動し、ドライブから読み込み、ネットワーク上でコンテンツをストリーミングし、ハッシュを計算します。いずれの場合でもボトルネックが発生する可能性があります。 Andrew Cooperが示唆したように、これらのファイルのいくつかを別々のファイルに対して並行して実行することができます。 – wigy

答えて

3

ボトルネックは、ファイル全体をネットワーク経由でコピー/ストリーミングする必要があるということです、そしてあなたは、ほぼ同じ計算時間

持っている良い... 異なるハッシュ関数(MD5/SHA256/SHA512)を見ているようですこの問題の

2つの解決策:

1)リモートシステム上で調理人を実行し、別々のファイルにしてハッシュを保存する - それがあなたの環境で可能な場合。

2)ファイルの一部のみをコピーできるように、ファイルの部分的なハッシュを作成します。あなたが読むことが最適であるので、ハッシュはユニークな滞在どのファイルの一部をテストする必要が

part1Hash = md5(file.getXXXBytesFromFileAtPosition1) 
part2Hash = md5(file.getXXXBytesFromFileAtPosition2) 
part3Hash = md5(file.getXXXBytesFromFileAtPosition3) 
finalHash = part1Hash^part2Hash^part3Hash; 

: は、私はそのようなことを意味します。

役立ちます希望...

編集:ビット単位のXORに変更

+1

ハッシュを組み合わせると、ビット単位のXORを使用するほうがはるかに良いでしょう。 ORを使用すると、1よりも多くの1を持つハッシュが生成され、ハッシュの衝突の可能性がはるかに高くなります。 –

+0

@andrew:ありがとう、それを変更しました。 – CaptainPlanet

+0

クライアント側に何かをインストールできない場合は、ここで#2に進みます。 100MBit/sは理論上のものであり、ネットワーク上の他の人たちを考慮していないため、帯域幅はあなたの敵です。理論的には誰かがこのタイプのアルゴリズムを壊すことは可能ですが、もしそうなら、それらをNSAに報告することができ、それらは取り除かれます。数ブロックのブロックを読み、ハッシュします。バイト数が増えるほどパフォーマンスは向上しますが、パフォーマンスに基づいて調整する必要があります。 –

1

ポートで聴いている各クライアントに「クライアント」をインストールしないと、要求されたファイルのMD5ハッシュが計算されます。

メインサーバーは、各クライアントにMD5の計算を依頼する必要があります。この分散型アプローチを使用すると、すべてのクライアントの総合的な速度が得られ、ネットワークの輻輳が軽減されます。

+0

ファイルサーバが独自のOSを持つNASデバイスである場合、これは機能しません。 –

+0

ネットワーク上のすべてのデバイスに対して、クライアントがあるかどうかを確認するフラグを保持します。そうであればそれを使用し、それ以外の場合は現行の方法を使用してください...これは複雑になり、独自の問題がありますが、速度とネットワークの両方に役立ちます。 – andrewjs

+0

あなたのアドバイスをありがとう。クライアントマシン上のハッシュ値を計算するプログラムの作成を検討しようとしています。うまくいけば、それは私達にそれをする方法を与えるでしょう。そして、UNCパス上のファイルに対しても、これらのマシンの処理能力を使用することができます。 –

3

1つの可能なアプローチは、.NET 4.0における並列タスクのライブラリーを利用することだろう。 100Mbpsは依然としてボトルネックになりますが、控えめな改善が見られるはずです。

私は昨年、フォルダとファイルのセキュリティ設定をチェックするフォルダツリーのトップレベルを歩く小規模なアプリケーションを作成しました。 10MbpsのWAN上で実行すると、大きなファイル共有の1つを完了するまでに約7分かかりました。私が操作を並列化すると、実行時間は1分を少し上回っていました。

+0

残念ながら、.NET 4.0ライブラリにアクセスすることはできません。私は、チャンク内のファイルのハッシュ値を計算するために複数のスレッドを作成するかどうかを調べる可能性があります。ファイルの一部をハッシュしてファイル全体のMD5を取得する方法についての投稿を見ました。 –

関連する問題