2016-04-25 4 views
1

文字列の整数ハッシュコードを生成したいが、これは永遠に続く。つまり、同じ文字列は常に同じハッシュコードになるはずです。文字列の永続ハッシュコード

ハッシュは暗号で安全である必要はなく、パスワードや機密データには使用されません。

最初の試みは.net framework 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; 

これはハッシュコードが一定ではないだろうことを示していると思われる: ただしソースを読めば、私は次のようcommmentを見つけました。

もしそうなら、フレームワークは繰り返し可能なハッシュコードを生成する別の方法を持っていますか?またはGetHashCodeのコードは、自分自身を実装するための合理的な出発点ですか?

私は可能な限り軽量で速いものを探しています。
私はSystem.Security.Cryptography.MD5を見つけましたが、単純なint32ハッシュコードではそれが過剰ですが、オーバーヘッドが心配です。少なくとも、文字列からバイト配列、バイト配列からintへの変換、および各ハッシュの新しいMD5()オブジェクトの作成、またはいくつかの静的共有MD5オブジェクト()の管理が必要です。

+1

"文字列ハッシュコードアルゴリズム"の場合は、良い結果が得られます。誰かがコードをコピーしてここに投稿する必要はありません。 – usr

+0

ハッシュコードを生成するための未知の品質のコードサンプルは必要ありません。これは、あらゆるフレームワークの根本的な必要性のように思えるので、私は.netフレームワークメソッドまたはメソッドの組み合わせを探しています。私はstring.GetHashCodeが明らかにこの目的には役に立たないと驚いていました。私は適切な選択肢を見つけることができませんでした。さらに、この機能がフレームワーク内に隠れている場所や、存在しない場所を示す、私と同様に他の人たちにも答えが役立つと期待しています。 – HugoRune

+0

最終的に良い結果を得た検索用語は、 ".net stable string hash code"でした。 – usr

答えて

9

文字列のハッシュコードを取得するには、安定したクロスバージョンが組み込まれていません。

既存のGetHashCode()コードをコピーするだけですが、ビルド番号をシードとして追加する部分は除外し、実装の詳細変更から安全を守るために安全でない呼び出しは使用しないでください。

int^charの動作が変更されない限り、無作為化を使用せず、将来のすべてのバージョンの.NETで同じ値を返す、完全に管理された64bit GetHashCode()のバージョンです。

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); 
     } 
    } 
} 
+0

btwこれはString.csの現在の(4.5/4.6)実際のGetHashCodeに近いです。 –

+0

@JonathanNappee私はそれが答えにString.csにリンクしていると言っていました。しかし、 "本当の"ものはポインタを使用し、文字列が 'char *'にどのようにマップされるかの実装の詳細に依存しています。ポインタを使うのはやや速いですが、文字列がメモリにどのように格納されるかの変更がハッシュコードを変更するため、将来の証明とはなりません。 –

+0

私の悪い、リンクが指していた場所が見えませんでした。 –

関連する問題