webentwicklung-frage-antwort-db.com.de

hash-Funktion in Python

Ich habe geglaubt, dass die Funktion hash() in allen Python-Interpreters gleich funktioniert. Es unterscheidet sich jedoch, wenn ich es auf meinem Handy mit Python für Android laufe. Ich bekomme denselben Hashwert für das Hashing von Strings und Zahlen, aber wenn ich eingebaute Datentypen hasse, unterscheidet sich der Hashwert.

PC Python Interpreter (Python 2.7.3)

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

Mobile Python Interpreter (Python 2.6.2)

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

Kann mir jemand sagen, ob es ein Fehler ist oder ich etwas falsch verstanden habe.

26
bkmagnetron

für alte Python (zumindest meine Python 2.7) scheint es das

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

und für CPython id() ist die Adresse im Speicher - http://docs.python.org/2/library/functions.html#id

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

meine Vermutung ist also, dass der Android-Port eine seltsame Konvention für Speicheradressen hat.

in Anbetracht der obigen Ausführungen unterscheiden sich die Hashwerte für Typen (und andere integrierte Komponenten) bei allen Installationen, da sich die Funktionen an unterschiedlichen Adressen befinden.

im Gegensatz dazu werden Hashwerte für Werte (was ich denke, Sie meinen "nicht-interne Objekte") (bevor zufälliges Material hinzugefügt wurde) aus ihren Werten berechnet und daher wahrscheinlich wiederholbar.

PS, aber es gibt mindestens noch eine CPython-Falte:

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

es gibt hier eine Antwort, die diese erklärt ...

8
andrew cooke

hash() wird standardmäßig jedes Mal zufällig ausgewählt, wenn Sie eine neue Instanz der neuesten Versionen (Python3.3 +) starten, um das Einfügen von Wörterbuch-DOS-Angriffen zu verhindern

Zuvor war hash() für 32-Bit- und 64-Bit-Builds ohnehin unterschiedlich.

Wenn Sie möchten, dass etwas jedes Mal dasselbe Hash ausführt, verwenden Sie einen der Hashes in hashlib

>>> import hashlib
>>> hashlib.algorithms
('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
35
John La Rooy

Bei CPython gibt aus Effizienzgründen hash() an internen Objekten den gleichen Wert zurück wie id() , der wiederum den Speicherplatz ("Adresse") des Objekts zurückgibt.

Von einem CPython-basierten Interpreter zu einem anderen Speicherplatz eines solchen Objekts können sich Änderungen ergeben. Je nach Betriebssystem kann sich dies von einem Lauf zum anderen ändern.

1
Sylvain Leroux

Das Hashing von Dingen wie int hängt von id () ab, was nicht garantiert ist, dass es zwischen den Läufen oder zwischen den Interpreten konstant ist. Das heißt, hash (int) erzeugt während eines Programmlaufs immer dasselbe Ergebnis, vergleicht jedoch möglicherweise nicht alle Läufe auf derselben Plattform oder auf verschiedenen Plattformen.

Übrigens: Die Hash-Randomisierung ist zwar in Python verfügbar, jedoch standardmäßig deaktiviert. Da Ihre Strings und Zahlen gleichermaßen Hashing sind, geht es hier natürlich nicht darum.

1
Sneftel

Von Python 3.3 aus hat der Standard-Hash-Algorithmus Hash-Werte erstellt, die mit einem zufälligen Wert gesalzen sind, der sogar zwischen verschiedenen Python-Prozessen auf derselben Maschine unterschiedlich ist.

Die Hash-Randomisierung wird derzeit nur für Zeichenfolgen implementiert, da sie als wahrscheinlichster Datentyp angesehen wurde, der von außen erfasst wurde und angegriffen werden konnte.

Dasselbe Frozenset erzeugt auf verschiedenen Maschinen oder sogar verschiedenen Prozessen durchgängig denselben Hashwert

Quelle: https://www.quora.com/Do-two-computers-produce-the-same-hash-for-identical-objects-in-Python

0
nabiltos