回答:
Pythonはランダムなハッシュシードを使用して、攻撃者が衝突するように設計されたキーを送信することにより、アプリケーションをタールピットするのを防ぎます。元の脆弱性の開示を参照してください。ランダムシード(起動時に1回設定)でハッシュをオフセットすることにより、攻撃者はどのキーが衝突するかを予測できなくなります。
PYTHONHASHSEED
環境変数を設定することで、固定シードを設定したり、機能を無効にしたりできます。デフォルトはですrandom
が0
、機能を完全に無効にして、固定の正の整数値に設定できます。
Pythonバージョン2.7および3.2では、この機能がデフォルトで無効になっています(-R
スイッチを使用するか、設定PYTHONHASHSEED=random
して有効にします)。Python 3.3以降ではデフォルトで有効になっています。
Pythonセットのキーの順序に依存している場合は、そうしないでください。Pythonはハッシュテーブルを使用してこれらの型を実装し、その順序は挿入と削除の履歴、およびランダムハッシュシードに依存します。Python 3.5以前では、これは辞書にも当てはまります。
object.__hash__()
特別なメソッドのドキュメントも参照してください:
注:デフォルトでは
__hash__()
、str、bytes、およびdatetimeオブジェクトの値は、予測できないランダムな値で「ソルト化」されます。それらは個々のPythonプロセス内で一定のままですが、Pythonの繰り返し呼び出し間で予測することはできません。これは、dict挿入の最悪の場合のパフォーマンス、O(n ^ 2)の複雑さを悪用する慎重に選択された入力によって引き起こされるサービス拒否に対する保護を提供することを目的としています。詳細については、http://www.ocert.org/advisories/ocert-2011-003.htmlを参照してください。
ハッシュ値を変更すると、辞書、セット、およびその他のマッピングの反復順序に影響します。Pythonはこの順序付けを保証していません(通常、32ビットビルドと64ビットビルドの間で異なります)。
もご覧ください
PYTHONHASHSEED
。
安定したハッシュ実装が必要な場合は、おそらくhashlib
モジュールを確認する必要があります。これは暗号化ハッシュ関数を実装しています。pybloomプロジェクトは、このアプローチを使用しています。
オフセットはプレフィックスとサフィックス(それぞれ開始値と最終XOR値)で構成されるため、残念ながらオフセットを格納することはできません。プラス面では、これは攻撃者がタイミング攻撃でもオフセットを簡単に決定できないことを意味します。
disable
を0に設定するときに、なぜそれを呼び出すのですか?何か不足している場合を除いて、古い安定したシード番号に設定することの効果的な違いはわかりません。PYTHONHASHSEED=12345
つまり、私が使用すると、セッション全体で同じ文字列に対して同じハッシュが得られます-使用すると同じことが起こります- PYTHONHASHSEED=0
等しい文字列のハッシュは、セッション間で同じになります(12345とは異なりますが、それは明白です)作業)。
0
シードはまったくなく、オブジェクトのハッシュは、ハッシュシードサポートのない古いバージョンのPythonで生成されたものと同じです。
Python 3では、ハッシュのランダム化がデフォルトでオンになっています。これはセキュリティ機能です。
ハッシュのランダム化は、dict構造の最悪の場合のパフォーマンスを悪用する慎重に選択された入力によって引き起こされるサービス拒否に対する保護を提供することを目的としています
2.6.8からの以前のバージョンでは、コマンドラインで-RまたはPYTHONHASHSEED環境オプションを使用してオンにすることができました。
PYTHONHASHSEED
ゼロに設定することでオフにできます。
hash()はPythonの組み込み関数であり、これを使用してstringやnumではなく、objectのハッシュ値を計算します。
詳細については、https://docs.python.org/3.3/library/functions.html#hashのページをご覧ください。
hash()の値は、オブジェクトの__hash__メソッドから取得されます。ドキュメントは次のように述べています:
デフォルトでは、str、bytes、およびdatetimeオブジェクトのハッシュ()値は、予測できないランダムな値で「ソルト化」されます。それらは個々のPythonプロセス内で一定のままですが、Pythonの繰り返し呼び出し間で予測することはできません。
そのため、別のコンソールで同じ文字列のハッシュ値が異なります。
あなたが実装することは良い方法ではありません。
文字列のハッシュ値を計算したい場合は、hashlibを使用してください
hash()は、スターリングではなく、オブジェクトのハッシュ値を取得することを目的としています。
hash()
文字列または数値に対して完全に有効です。これを、ハッシュ値のカスタム実装を提供するため__hash__
に使用されるhash()
カスタムメソッドと混同しています。