文字列に対して、永久に一定のままの整数ハッシュコードを生成したいです。つまり、同じ文字列は常に同じハッシュコードになるはずです。
ハッシュは暗号的に安全である必要はなく、パスワードや機密データには使用されません。
最初の試みは、.net フレームワークの string.GetHashCode() 関数を使用することでした。しかし、ソースを読んでみると、次のコメントが見つかりました。
// We want to ensure we can change our hash function daily. // This is perfectly fine as long as you don't persist the // value from GetHashCode to disk or count on String A // hashing before string B. Those are bugs in your code. hash1 ^= ThisAssembly.DailyBuildNumber;
これは、ハッシュコードが一定ではないことを示しているようです。
もしそうなら、フレームワークには繰り返し可能なハッシュコードを生成する別の方法がありますか? それとも、GetHashCode のコードは、独自のコードを実装するための適切な出発点になりますか?
できるだけ軽量で高速なものを探していました
。システム.セキュリティ.暗号化.MD5しかし、単純な int32 ハッシュコードにはやりすぎのようで、オーバーヘッドが心配です。少なくとも、文字列からバイト配列への変換、バイト配列から int への変換、MD5()
ハッシュごとに新しいオブジェクトを作成するか、静的な共有 MD5 オブジェクト () の管理が必要になります。
ベストアンサー1
文字列のハッシュ コードを取得するための、バージョン間で安定した組み込みの方法はありません。
既存のGetHashCode()
コードをコピーするだけで、ビルド番号をシードとして追加する部分を除外し、実装の詳細の変更から身を守るために安全でない呼び出しを使用しないでください。
こちらは完全に管理されたバージョンです64ビットGetHashCode()
int ^ char
ランダム化は使用されず、.NET の将来のすべてのバージョンで同じ値を返します (の動作が変更されない限り)。
public static class StringExtensionMethods
{
public static int GetStableHashCode(this string str)
{
unchecked
{
int hash1 = 5381;
int hash2 = hash1;
for(int i = 0; i < str.Length && str[i] != '\0'; i += 2)
{
hash1 = ((hash1 << 5) + hash1) ^ str[i];
if (i == str.Length - 1 || str[i+1] == '\0')
break;
hash2 = ((hash2 << 5) + hash2) ^ str[i+1];
}
return hash1 + (hash2*1566083941);
}
}
}