web-dev-qa-db-ja.com

C#バイト配列またはイメージのハッシュを作成する

可能性のある複製:
c#のバイト配列からハッシュコードを生成する方法

C#では、イメージのハッシュを作成して、ストレージ内で一意であることを確認する必要があります。

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

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

38
johnc

.NETには、暗号化ハッシュを作成するハッシュサムプロバイダーがたくさんあります。これにより、ハッシュが固有であるという条件が満たされます(ほとんどの場合、衝突防止)。それらはすべて非常に高速であり、1兆回以上実行しない限り、ハッシュがアプリのボトルネックになることはありません。

個人的に私はSHA1が好きです:

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

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

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

60
Rex M

SHA1を使用してハッシュを生成する Rex M's answer の部分は良いものです(MD5も一般的なオプションです)。常に新しい暗号プロバイダーを作成しないことに関するzvolkovの提案も適切です(仮想的に保証された一意性よりも速度が重要な場合にCRCを使用することに関する提案と同様)。

ただし、notEncoding.UTF8.GetString() を使用して、byte []を文字列に変換します(もちろんコンテキストから、それが有効なUTF8であることがわかります)。まず、それは 無効な代理を拒否する になります。常にbyte []から有効な文字列を提供することが保証されているメソッドは Convert.ToBase64String() です。

15
Jonathan Rupp

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

それでも、暗号化用に設計されたハッシュ関数は、GetHash()オーバーライドに必要な非常に小さなハッシュサイズ(32ビット)ではうまく機能しないため、暗号化ハッシュの代わりに多くのCRCアルゴリズムのいずれかを実行します(それがあなたが望むものだと仮定します)。

C#でCRCを計算する1つの例については、このリンクを確認してください。 http://sanity-free.org/134/standard_crc_16_in_csharp.html

追伸ハッシュを小さく(16ビットまたは32ビット)したいのは、それらをFASTで比較できるようにするためです(これがハッシュを持つことの重要なポイントでしたね)。 256ビットのlong値で表されるハッシュを文字列としてエンコードすることは、パフォーマンスの点で非常に異常です。

5
zvolkov

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

それを除けば、可能性の高いIDをチェックするために、MD5はかなり高速です。 SHAは信頼性が高いです(MD5はハッキングされているため、セキュリティには使用しないでください)。ただし、速度も遅くなります。

4
Adam Robinson