hash-Funktion in Python 3.3 gibt unterschiedliche Ergebnisse zwischen den Sitzungen
Habe ich umgesetzt, ein BloomFilter in python 3.3, und bekam unterschiedliche Ergebnisse jeder Sitzung. Drilldown dieses seltsame Verhalten hat mich auf die interne hash () - Funktion - es gibt verschiedene hash-Werte für die gleichen string in jeder session.
Beispiel:
>>> hash("235")
-310569535015251310
----- öffnen Sie eine neue python-Konsole -----
>>> hash("235")
-1900164331622581997
Warum ist das passiert?
Warum ist dies nützlich?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Python verwendet eine zufällige hash-Saatgut zu verhindern, dass Angreifer von tar-Messen Sie Ihre Anwendung, indem Sie Sie Tasten ausgelegt zu kollidieren. Finden Sie die original Offenlegung der Sicherheitsanfälligkeit. Durch Verrechnung der Hashwert mit einem random seed (einmal beim Start) Angreifer kann nicht mehr voraussagen, was werden die Schlüssel kollidieren.
Können Sie einen festen Samen-oder deaktivieren Sie die Funktion, indem Sie die
PYTHONHASHSEED
environment variable; der Standardwert istrandom
aber Sie können legen Sie es auf eine Feste positive ganze Zahl mit dem Wert, mit0
deaktivieren Sie die Funktion vollständig.Python-Versionen 2.7 und 3.2 haben die Funktion standardmäßig deaktiviert (verwenden Sie die
-R
wechseln oder setPYTHONHASHSEED=random
um es zu aktivieren); Sie ist standardmäßig aktiviert, Python 3.3 und höher.Wenn Sie sich auf die Reihenfolge von Schlüsseln in einem Python-dictionary oder gesetzt wird, dann nicht. Python verwendet eine hash-Tabelle zu implementieren, die diese Typen und Ihre Reihenfolge hängt von der Einfügung und Löschung der Geschichte sowie die random-hash-seed.
Siehe auch die
- Objekt.__hash__()
spezielle Methode Dokumentation:Benötigen Sie ein stabiles hash-Implementierung, werden Sie wahrscheinlich wollen, schauen Sie sich die
hashlib
- Modul; dies implementiert kryptografische hash-Funktionen. Die pybloom Projekt verwendet diesen Ansatz.Da der offset besteht aus einem Präfix und einem suffix (start-Wert und die endgültige XORed Wert, beziehungsweise) Sie können nicht nur speichern des Offsets, leider. Auf der positiven Seite bedeutet dies, dass die Angreifer nicht so leicht ermitteln Sie den offset mit timing-Angriffe entweder.
disable
bei der Einstellung 0 werden? Ich sehe nicht den effektiven Unterschied zu der Einstellung alle alten stabilen, seed-Nummer, es sei denn, ich bin fehlt etwas. Was ich meine ist, wenn ichPYTHONHASHSEED=12345
bekomme ich den gleichen hash für gleiche strings auch über Sitzungen - das gleiche passiert, wenn ichPYTHONHASHSEED=0
- der hash für gleiche Zeichenfolgen werden die gleichen sein, über mehrere Sitzungen (wenn auch anders 12345, aber es ist offensichtlich, dass, wie die Samen arbeiten).0
es gibt keine Samen, und die hashes für Objekte gleich erzeugt, die in eine ältere Python-version ohne hashseed unterstützen.PYTHONHASHSEED=0
erzeugen soll, die gleichen hash-Werte als Python 2.6 für die gleichen string-input. Die option besteht, da die Produktionsanlagen mussten in der Lage sein, um den übergang von Versionen ohne Randomisierung zu eins mit, aber halten Sie kompatibel, während des übergangs.Hash-Randomisierung ist standardmäßig aktiviert in Python 3. Dies ist ein Sicherheits-feature:
In früheren Versionen von 2.6.8, Sie könnten schalten Sie es auf der Kommandozeile mit -R, oder die PYTHONHASHSEED Umgebung option.
Können Sie ausschalten, indem Sie die Einstellung
PYTHONHASHSEED
auf null.hash() ist ein Python - built-in-Funktion und verwenden Sie zur Berechnung einen hash-Wert für Objekt, nicht für string oder num.
Sehen Sie die Details auf dieser Seite: https://docs.python.org/3.3/library/functions.html#hash.
- und hash () - Werte von dem Objekt kommt ' s __hash__ Methode.
Der doc sagt Folgendes:
Das ist, warum Ihr haben unterschiedliche hash-Wert für die gleiche Zeichenfolge in der anderen Konsole.
Was Sie umsetzen, ist nicht ein guter Weg.
Wenn Sie berechnen möchten, eine string-hash-Wert, verwenden Sie einfach hashlib
hash() ist erklärtes Ziel, eine Objekt-hash-Wert, nicht einen stirng.
hash()
ist vollkommen gültig für string-oder numerischen Werten. Du verwechselst dies mit der__hash__
benutzerdefinierten Methode verwendet werden durchhash()
, um eine benutzerdefinierte Implementierung der hash-Wert.