27

hash()関数はすべての Python インタープリターで同じように機能すると信じていました。しかし、 python for androidを使用してモバイルで実行すると異なります。文字列と数値をハッシュする場合は同じハッシュ値を取得しますが、組み込みのデータ型をハッシュするとハッシュ値が異なります。

PC Python インタープリター (Python 2.7.3)

>>> hash(int)
31585118
>>> hash("hello sl4a")
1532079858
>>> hash(101)
101

モバイル Python インタープリター (Python 2.6.2)

>>> hash(int)
-2146549248
>>> hash("hello sl4a")
1532079858
>>> hash(101)
101

バグなのか、何かを誤解しているのか、誰にでも教えてもらえますか。

4

5 に答える 5

36

hash()最近のバージョン (Python3.3+) の新しいインスタンスを起動するたびにデフォルトでランダム化され、辞書挿入 DOS 攻撃を防ぎます

それ以前は、hash()とにかく 32 ビットと 64 ビットのビルドで異なっていました。

毎回同じものにハッシュするものが必要な場合は、hashlib のハッシュの 1 つを使用します

>>> import hashlib
>>> hashlib.algorithms
('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
于 2013-06-19T13:34:47.730 に答える
10

古いpython(少なくとも、私のPython 2.7)の場合、

hash(<some type>) = id(<type>) / 16

CPythonid()の場合、メモリ内のアドレスです- http://docs.python.org/2/library/functions.html#id

>>> id(int) / hash(int)                                                     
16                                                                              
>>> id(int) % hash(int)                                                 
0                                                                               

私の推測では、Android ポートにはメモリ アドレスに関する奇妙な規則があるのでしょうか?

とにかく、上記を考えると、関数は異なるアドレスにあるため、タイプ(および私が推測する他の組み込み)のハッシュはインストールごとに異なります。

対照的に、値のハッシュ(「非内部オブジェクト」の意味だと思います)(ランダムなものが追加される前)は、それらの値から計算されるため、繰り返し可能です。

PS しかし、少なくとももう 1 つの CPython のしわがあります。

>>> for i in range(-1000,1000):
...     if hash(i) != i: print(i)
...
-1

それを説明する答えがどこかにあります...

于 2013-06-19T13:43:21.127 に答える
1

CPython では、内部オブジェクトの効率上の理由から、オブジェクトのメモリ位置(「アドレス」) をhash()返すのと同じ値を返します。id()

ある CPython ベースのインタープリターから、そのようなオブジェクトの別のメモリ ロケーションへの移動は、変更される可能性があります。OS によっては、実行ごとに異なる場合があります。

于 2013-06-19T13:58:44.117 に答える