2016-04-01 8 views
2

辞書から既存のキーハッシュを抽出し、再計算する必要はありませんか?再計算なしで辞書キーを取得する

ハッシュでキーではなく辞書にアクセスすると、それらを公開してしまう危険性は何ですか?

+1

あなたが何を求めているのか分かりません。ハッシュとキーは等価ではありません - ハッシュは衝突することができますが、キーは衝突できません。あなたがハッシュの内部を調べて各エントリを調べることができれば、それは実装に依存すると思いますが、これはCPythonにはありません –

+1

'for my_dict:print hash(key)'おそらく... –

+0

@JoranBeasley技術的には、これらのハッシュを再計算することもできます( '__hash__'実装はハッシュをキャッシュすることができますが、保証されません) –

答えて

2

Pythonの辞書オブジェクトには、オブジェクトが保存されているハッシュを見ることができる公開APIはありません。 Pythonコードでオブジェクトをハッシュで直接格納することはできません(CPythonの内部C関数を呼び出すことで可能です)。キーではなく、ハッシュ値で辞書に値を追加できない理由はいくつかあります。

最も明白なことは、複数のキーオブジェクトが同じハッシュを持つ可能性があることです。このようなハッシュの衝突が発生した場合、2番目の値がハッシュテーブルのどこかに挿入されます。重要なことは、同じ値をハッシュする別のキーの下に格納されていた以前の値を上書きしないことです。ハッシュでもキーでもない場合、Pythonは同じキーを使用しているかどうか、または衝突したハッシュを持つ新しいキーを提供しているかどうかを知ることができません。

ハッシュで挿入できない第2の理由は、セキュリティ上の脆弱性であるということです。ハッシュの衝突が少ない場合、Pythonの辞書などのハッシュテーブルのパフォーマンスは非常に優れています。しかし、すべてのハッシュが同じであれば、非常に悪いです。すべて同じ値にハッシュしたPythonプログラムにデータを提出できれば、非常に効率的なサービス拒否攻撃を行うことができます(最近のバージョンのPythonでは、この種の攻撃を困難にするために新しいハッシュランダム化が追加されました)。

+0

まあ、これを返すカスタム' __hash__'メソッドを用意することで、値と内容にかかわらず、単純に比較結果が異なります –

+0

これを正確に実行します:ハッシュ - > datadump(値または値のリスト)を提供することによってdictを照会します。 Dictオブジェクトのイントロスペクション –

2

A Pythonのdictのキー、すなわち、__hash__特別な方法(並びに質問に無関係ないくつかの他の方法)を実装し、hashableこと、またはいくつかの所定のタイプに内蔵のものでなければなりません。だから、実際に

>>> '123'.__hash__() 
163512108404620371 

かによって、例えばテーブル、なしでキーのハッシュ値にアクセスすることができ、より均一に

>>> hash('123') 
163512108404620371 
>>> hash(2) 
2 

コメント、ハッシュ値とで述べたように、言われていることテーブル内の位置は同じではありません。実際、テーブルのサイズが変更されると、キーのハッシュ値は同じままですが、位置は変更される可能性があります。その結果、として:

  • ハッシュ値がhash()

  • を経由してあなたに容易に入手可能である位置は、辞書の内部状態を公開します

  • 簡単にあなたのオブジェクト内のハッシュ値を「キャッシュ」することができます__hash__の方法では十分です

キーが公開されていない可能性があります'ポジション。

+0

メソッドに直接行くのではなく、 'hash()'組み込み関数を使うこともできます。 – zondo

+0

ありがとう、@ zondo - 私はすでにそれを更新しましたが、私はコメントに感謝します。 –

+0

@ zondoしかし、OPの動機づけはハッシュ値の再計算を避けることでしたので、このメソッドについて言及することは重要でした。私の主張は、 '__hash__'メソッド内にキャッシュできるということでした。 –

関連する問題