7

最近興味深い問題が出てきました。MD5 暗号化のソルト ソースとして使用しているコードに遭遇しhashCode()ましたが、これにより疑問が生じます:hashCode()異なる VM、異なる JDK バージョン、およびオペレーティング システムで同じオブジェクトに対して同じ値を返すでしょうか? 保証されていなくても、今までに何か変わったことはありますか?

編集:もちろん、オーバーライドできるString.hashCode()より一般的な ではなく、本当に意味します。Object.hashCode()

4

5 に答える 5

9

いいえ。http://tecfa.unige.ch/guides/java/langspec-1.0/javalang.doc1.htmlから:

hashCode の一般的な規約は次のとおりです。

  • Java アプリケーションの実行中に同じオブジェクトに対して複数回呼び出された場合は常に、hashCode は一貫して同じ整数を返す必要があります。整数は、正、負、またはゼロのいずれかです。ただし、この整数は、1 つの Java アプリケーションから別のアプリケーションへ、またはアプリケーションの 1 つの実行から同じアプリケーションの別の実行へと一貫性を保つ必要はありません。[...]
于 2008-10-10T07:14:19.773 に答える
4

タイプによって異なります。

  • hashCode() をオーバーライドしていない型を取得した場合、プログラムを実行するたびに異なる hashCode() が返される可能性があります。
  • hashCode() をオーバーライドするタイプを持っているが、それがどのように計算されるかを文書化していない場合、同じデータを持つオブジェクトが実行ごとに異なるハッシュを返すことは完全に正当です。同じ実行内で呼び出します。
  • 文書化された方法で hashCode() をオーバーライドする型を持っている場合、つまりアルゴリズムが文書化された動作の一部である場合、おそらく安全です。(たとえば、java.lang.String はこれを文書化しています。) ただし、個人的には、一般的な原則に基づいてこれに依存することは避けたいと思います。

.NET の世界からの教訓: string.GetHashCode() の結果をデータベースのパスワード ハッシュとして使用することで、世界で少なくとも数人の人々が苦しんでいるのを見てきました。.NET 1.1 と 2.0 の間でアルゴリズムが変更され、突然すべてのハッシュが「間違った」ものになりました。(Jeffrey Richter は、C# を介した CLR でほぼ同じケースを文書化しています。) ハッシュを格納する必要がある場合、常に安定していることが保証される方法で計算することをお勧めします。たとえば、MD5 またはによって実装されたカスタム インターフェイスです。安定性を保証するあなたのタイプ。

于 2008-10-10T08:02:33.873 に答える
3

ドキュメントによると: String オブジェクトのハッシュコードは次のように計算されます

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

これが正式な仕様なのか、単なる Sun の実装なのかはわかりません。少なくとも、プラットフォームやオペレーティング システムに関係なく、既存のすべての Sun VM で同じである必要があります。

于 2008-10-10T15:24:23.500 に答える
1

いいえ。別段の指定がない限り、ハッシュ アルゴリズムは保証されません。したがって、たとえば、ハッシュ構造の逆シリアル化ではハッシュ コードを再計算する必要があり、これらの値はシリアル化された形式で格納しないでください。

于 2008-10-10T08:08:13.610 に答える
0

ビジネスオブジェクトがどこでも同じ hashCode を返すようにするために、 hashCode() をオーバーライドできることを付け加えておきます (そうする場合は equals() を忘れないでください)。これらのオブジェクトは、少なくとも予測可能な hashCode を持ちます。

于 2008-10-10T07:38:31.020 に答える