5

重複の可能性:
データベースに安全に格納できる文字列の HashCode を .net (c#) で作成するにはどうすればよいですか?

データベースに何十万もの URL を保存することを計画しています。UrlInfo テーブルの各行は、URL 自体が論理的な主キーであり、変更できません。URL はかなり長くなる可能性があるため、新しい行を追加するときに一致する可能性のあるものをすばやく見つける方法として、URL をハッシュすることにしました。ハッシュは私の真のキーではなく、可能な一致をすばやく見つける方法です。さらに、ドメインごとに RegEx パターンを使用して、URL の本質を抽出し、他の URL と比較できるようにしています。正規表現の結果もハッシュとして保存していますが、重複の可能性があるかどうかは心配していません。

物事をハッシュするために使用してきた C# の string.GetHashCode() メソッドが、.Net の実装間で一意であることが保証されていないことを知るまで、すべてが順調に進んでいました。これは、ハッシュ関数を ASP.Net から SQLServer CLR コードに移動しようとしたときに気付きました。Web アプリは .Net 4.0 を使用し、SQLServer 2008 R2 は .Net 3.5 を使用していることを知りました。同じ文字列に対して個別のハッシュ結果が得られたため、string.GetHashCode() を使用しないようにする必要があります。これは、アプリを将来のバージョンの .Net にアップグレードするときにこの変更について心配する必要がないためです。

だから、質問:

  1. データベースにハッシュを保存しているため、アーキテクチャの臭いはありますか? より良い方法はありますか?明らかに、Microsoft は私がハッシュ結果を保存することを望んでいません!

  2. 文字列をハッシュするための優れた C# 置換アルゴリズムを誰かが推奨できますか? Jon's hereを見ましたが、文字列に対して機能するように変更する方法が正確にはわかりません(ASCIIコードを使用して各文字をループしますか?)。

  3. ハッシュアルゴリズムを使用するよりも優れた文字列圧縮アルゴリズムはありますか?

ありがとう

多くの人から素晴らしい反応。どうもありがとうございます!!!

4

5 に答える 5

3

代わりに、いつでもMD5ハッシュを使用できます。これは、比較的高速です。

public string GetUrlHash(string url) {

    byte[] hash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(url));

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < hash.Length; i++) {
        sb.Append(hash[i].ToString("X2"));
    }

    return sb.ToString();
}

そのように呼んでください:

Console.WriteLine(this.GetUrlHash("http://stackoverflow.com/questions/5355003/storing-c-gethashcode-in-db-is-unreliable"));

そして取得:

> 777BED7F83C66DAC111977067B4B4385

これは、一意性の観点からかなり信頼できるはずです。MD5は現在、パスワードアプリケーションに対して安全ではありませんが、ここではその問題はありません。

唯一の問題は、このような文字列をテーブルの主キーとして使用すると、パフォーマンスの面で問題が発生する可能性があることです。

もう1つできることは、URL短縮アプローチを使用することです。データベースのシーケンス生成機能を使用し、値をBase36のようなものに変換します(LONGまたはBIGINTに相当するものを使用してください)。これにより、簡潔でわかりやすい文字列が得られます。 。

于 2011-03-18T16:47:54.433 に答える
1

同様の質問がここで尋ねられました:

データベースに安全に保存できる文字列のHashCodeを.net(c#)に作成するにはどうすればよいですか?

それはあなたの問題を解決することを証明するかもしれません。

于 2011-03-18T16:34:06.847 に答える
1

注として、2008年のSQL Serverは、関数HASHBYTESをサポートしています(持っています)。この関数は、一部のデータ(文字列など)を指定すると、MD2、MD4、MD5、SHA、またはSHA1ハッシュを生成できます。

于 2011-03-18T16:48:13.623 に答える
0

文字列を圧縮して VARBINARY を格納することを検討しましたか? はるかに小さい可能性があり、その上に直接インデックスを構築できます。

于 2011-03-18T18:35:49.047 に答える
0

おそらくハッシュを保存する必要はないと思います。

テーブル内の URL 列を正しくインデックス化 (一意のインデックス) していることを確認してください。これにより、検索が高速になります。

于 2011-03-18T16:56:24.990 に答える