2011-06-21 7 views
3

C++について私はずっとビットシフト、XOR、素数を扱わずに良いハッシュ値を作成するためにBoost.Functional/Hashを使ってきました。 C#/ .NETの良い(私は最適を求めていない)ハッシュ値を生成するライブラリがありますか?このユーティリティを使用して、暗号化ハッシュではなくGetHashCode()を実装します。.NET用の「良い」ハッシュコードを作成するBoost.Functional/Hash

(GetHashCodeメソッドを実装する場合)(非常に一般的な操作ofcourseの)私は、これは便利だと思う理由を明確にするために、ここで値をハッシュする組み合わせboost::hash_combineの実装があります:

明らかに
seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 

、コードdoesnのこの種のGetHashCode()の実装に属しているため、他の場所で実装する必要があります。

+1

良いハッシュをどのように定義しますか?どのような目的のために?そしてなぜあなたは 'GetHashCode()'が気に入らないのですか? – CodesInChaos

+0

あなたはOPを誤解していると思います。彼はBoost.Functional/Hash *のようなものを 'GetHashCode' *の中で使うことを望んでいます! –

+1

関連:http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode – CodesInChaos

答えて

1

this questionの回答には、Boost.Functional/Hashに似たヘルパークラスの例がいくつか含まれています。しかし、どれも優雅には見えません。

私は同等の機能を提供する実際の.NETライブラリについて認識していません。

-3

このlinkを見てください。MD5ハッシングについて説明しています。 それ以外の場合は、GetHashCode()を使用します。

+0

-1:これは 'MyType.GetHashCode()'のために非常に高価になるでしょう。 – Richard

+0

OPは暗号ハッシュについて言及していません。さらに、GetHashCodeなどで使用されるハッシュ関数に似ています。http://msdn.microsoft.com/en/ -us/library/system.object。gethashcode.aspx – LukeH

+0

@Richard&@LukeH - 質問を注意深く読んでください。彼は最適な解決策を望んでいませんが、良い解決策を求めています。 – Bibhu

1

非常に特殊な要件がない限り、タイプのハッシュコードを第1の原則から計算する必要はありません。

int hash = field1.GetHashCode(); 
hash = (hash *37) + field2.GetHashCode(); 

(§ 3.3.2 C# in Depth, 2nd Ed, Jon Skeetから取られた合成機能):むしろあなたが簡単な方法、のようなものの一つに平等の決意のために使用するフィールド/プロパティのハッシュコードを兼ね備えています。

+1

31を使用しない37. 37は、辞書が容量として時々選択するため、縮退ハッシュにつながります。 – CodesInChaos

+2

@CodeInChaose:システム全体を考慮した場合、* any *値が縮退するケースが考えられます。自由に値を選んでください。一般的な答えでは、本質的に任意です。 – Richard

4

私はそれのためだけに別のライブラリを使用しませんでした。前に述べたように、GetHashCodeメソッドの場合、高速で安定していることが不可欠です。通常、私はインライン実装を作成することを好むが、ヘルパークラスを使用するために、実際には良い考えかもしれません:

internal static class HashHelper 
{ 
    private static int InitialHash = 17; // Prime number 
    private static int Multiplier = 23; // Different prime number 

    public static Int32 GetHashCode(params object[] values) 
    { 
     unchecked // overflow is fine 
     { 
      int hash = InitialHash; 

      if (values != null) 
       for (int i = 0; i < values.Length; i++) 
       { 
        object currentValue = values[i]; 
        hash = hash * Multiplier 
         + (currentValue != null ? currentValue.GetHashCode() : 0); 
       } 

      return hash; 
     } 
    } 
} 

共通ハッシュ計算ロジックを使用することができますこの方法:

public override int GetHashCode() 
{ 
    return HashHelper.GetHashCode(field1, field2); 
} 
0

ないようにするにはInt32

public static class HashHelper 
{ 
    public static int InitialHash = 17; // Prime number 
    private static int Multiplier = 23; // Different prime number 

    [MethodImpl(MethodImplOptions.AggressiveInlining)] 
    public static Int32 GetHashCode<T>(this Int32 source, T next) 
    { 
     // comparing null of value objects is ok. See 
     // http://stackoverflow.com/questions/1972262/c-sharp-okay-with-comparing-value-types-to-null 
     if (next == null) 
     { 
      return source; 
     } 
     unchecked 
     { 
      return source + next.GetHashCode(); 
     } 
    } 

} 

上の一般的な拡張メソッドを使用して、呼び出しが、あなたが

を行うことができますボクシング発行チェーン
HashHelper 
    .InitialHash 
    .GetHashCode(field0) 
    .GetHashCode(field1) 
    .GetHashCode(field2); 
関連する問題