2009-04-29 9 views
30

可能性の重複のためのハッシュを作成します。C#ので
How do I generate a hashcode from a byte array in c#C#、バイト配列または画像

、私はそれがストレージに一意であることを確認するために、画像のハッシュを作成する必要があります。

私は簡単にバイト配列に変換できますが、そこから進める方法はわかりません。

.NETフレームワークに私を助けることができるクラスがありますか、または効率的なアルゴリズムのようなユニークなハッシュを作成するアルゴリズムを知っている人はいますか?

答えて

43

.NETには暗号ハッシュを作成するハッシュサムプロバイダがたくさんあります。これらのハッシュプロバイダは、(ほとんどの目的で衝突防止のために)一意であるという条件を満たします。彼らはすべて非常にであり、あなたが1兆回以上それをやっていない限り、ハッシュは間違いなくアプリケーションのボトルネックにはなりません。

個人的に私は、SHA1が好き:

string hash; 
using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) 
{ 
    hash = Convert.ToBase64String(sha1.ComputeHash(byteArray)); 
} 

の人が一つの方法は、他よりも遅くなる場合がありますと言っても、それはすべての相対的な用語であります。画像を扱うプログラムは、ハッシュサムを生成するマイクロ秒プロセスに気付かないでしょう。

衝突については、ほとんどの場合、これも無関係です。 MD5のような「時代遅れの」方法さえも、ほとんどの状況で非常に有用です。システムのセキュリティがの場合は、衝突を防止するためにに依存している場合にのみ使用することをお勧めします。

+2

Rex I ' @AdamRobinsonが指摘しているように、SHA1などの.NET暗号化ハッシュを含むハッシュは一意性を保証できません;ハッシュが多対1のマッピングである限り、ハ可能な入力よりshcodes。 – Spike0xff

+2

@ Spike0xffソフトウェアでは、「一意」と言うとき、「十分にユニーク」を意味すると理解されています。私は、このスレッドの誰かがそれについて混乱しているという兆候は見ません。 –

+2

私の懸念事項は投稿する人だけではなく、誰でも読んでいることです。混乱していると必ず表示されるとは思いません。そして、私はそれが辞書の定義ではなく、それが私がそれを意味するかそれを理解する方法でもないので、あなたが「それが意味すると理解されることを願っています。たぶんあなたは評判の良い情報源を挙げることができますか? – Spike0xff

2

標準のハッシュアルゴリズムを使用できますが、ハッシュでは技術的に一意性が保証されません。ハッシングは、あるデータが他のデータと同じである可能性が高いかどうかを確認するために、比較的高速かつ/または小さなトークンになるように設計されています。完全に異なるデータセットが同じハッシュを生成することは完全に可能ですが、アルゴリズムで生成することは非常に困難です。

これ以外にも、身元を確認するために、MD5はかなり高速です。 SHAはより信頼性が高いです(MD5はハッキングされているため、セキュリティには使用しないでください)。しかし、それも遅くなります。

3

ハッシュを計算する必要があるたびに、SHA1CryptoServiceProviderの新しいインスタンスを作成することはまったく高速ではありません。同じインスタンスを使用するのはかなり速いです。

まだ暗号化用に設計されたハッシュ関数は非常に小さなハッシュサイズ(32ビット)で動作しないので、暗号ハッシュの代わりに多くのCRCアルゴリズムを実行したいと思っています。これはGetHash ()あなたが望むものと仮定して)オーバーライドします。 C#でCRCの計算の一例について

チェックこのリンクアウト:http://sanity-free.org/134/standard_crc_16_in_csharp.html

P.S.あなたのハッシュを小さくしたい理由(16または32ビット)は、あなたがそれらをFAST(それはハッシュを持つことの全ポイントでした、覚えていますか?文字列としてエンコードされた256ビットのlong値で表されるハッシュを持つことは、パフォーマンス面では非常識なことです。

11

SHA1を使ってハッシュを生成することについては、Rex M's answerの部分がいいです(MD5も一般的なオプションです)。常に新しい暗号プロバイダを作成しない程度zvolkovの提案は、速度が事実上保証一意性よりも重要である場合にはCRCを使用する方法についての提案であるとしても良いもの(である。

しかし、バイトを変換するない使用Encoding.UTF8.GetString()を行います[ ]は文字列に変換されます(もちろん、有効なUTF8であることをコンテキストから分かっている場合を除き)reject invalid surogatesバイトからの有効な文字列を常に保証するメソッドはConvert.ToBase64String()です。

+0

ありがとうございました。実際にそれは私がいつもしていることですが、私はそのサンプルを頭の上から投げ捨て、最初のバイトを頭に入れました。 –

+0

ヘッドアップありがとうジョナサン、編集Rexのおかげで – johnc