2

さまざまなタイプのカスタム ハッシュ コードを持つ API があります。これらのハッシュ コードは、問題のオブジェクトの文字列表現のハッシュの取得に基づいています。可能な限りハッシュ コードが衝突しないように、また、同等の文字列表現を持つ異なるタイプのオブジェクトが異なるハッシュ コードを持つように、さまざまなソルティング手法が使用されます。

明らかに、ハッシュ コードは文字列に基づいているため、いくつかの衝突があります (無限の文字列と 32 ビット整数の制限された範囲)。私はハッシュをセッション間で保持する必要があり、特にオブジェクトのデータベース ストレージで使用するために、文字列表現に基づくハッシュを使用します。

突然、今日私のコードはオブジェクトのさまざまなハッシュ コードを生成し始め、あらゆる種類のものを破壊しています。それは今日の早い段階で機能していましたが、ハッシュ コードの生成に関連するコードには一切触れていません。

.Net のドキュメントでは、.Net フレームワークのバージョン間 (および 32 ビット バージョンと 64 ビット バージョンの間) で変更するハッシュ コードの実装が許可されていることは承知していますが、私はフレームワーク バージョンを変更しておらず、フレームワークの更新も最近ありません。私が覚えているように

これは本当に奇妙に思えるので、何かアイデアはありますか?

編集

ハッシュコードは次のように生成されます。

//Compute Hash Code
this._hashcode = 
   (this._nodetype + this.ToString() + PlainLiteralHashCodeSalt).GetHashCode();
4

2 に答える 2

3

彼のコメントで StampedeXV が示唆しているのは、オーバーライドされていないObject.ToString()場合、デフォルトで完全修飾名を返すということです。ToString()

  1. 名前空間 (またはクラス名) を変更するToString()と、オーバーライドされていない場合、この値が変更されます。
  2. 明らかに、オーバーライドToString()すると変更されます。
  3. どこでどのように変更されているかを正確に確認します_nodeType
  4. PlainLiteralHashCodeSaltミステリーのままです(定数文字列だと思います)。
  5. 変更されないことを保証する人String.HashCode()はいないため、少なくとも Reflector を使用してメソッドのソースを取得し、ライブラリに含めることができます。これは私が通常お勧めするものではありませんが、今後はこれに依存したくありません。

言うまでもなく、3 つの値 (_nodeType、th​​is.ToString()、salt 文字列) をすべてトレースして、それらが変更されていないことを確認する必要があります。機能する古いリビジョンに戻すことができれば、道半ばです。

それとは別に、ハッシュ コードを永続化することはお勧めしません。これがパフォーマンスに関連している場合は、インデックス作成とハッシュ化を処理するのはデータベースの責任であることに注意してください。また、一意であることを保証できないため、GUID でもありません。それで、ポイントは何ですか?

しかし、これは既にデータベースにあるため、HashCode の実装を元に戻す方法が主な関心事です。

于 2009-10-14T13:22:33.517 に答える
1

このハッシュコードを永続化に使用しているとのことです。ToString()関数を使用してハッシュコードを生成するため、これは現在の実装では悪い考えです。この関数の結果は永続性とは関係がなく、おそらく開発者は GUI 設計または何らかの理由で変更する必要があり、永続性にも使用されることを忘れています。
あなたの場合、ToString()メソッドの結果を確認しますが、変更された可能性があります。これは、カルチャを変更したり、オブジェクトを別の名前空間に移動したりすることで発生する可能性があります。ちょっと見てください。理由が見つかるかもしれません。

于 2009-10-14T12:54:57.200 に答える