Python verwendet einen zufälligen Hash-Startwert, um zu verhindern, dass Angreifer Ihre Anwendung tarieren, indem Sie Schlüssel senden, die für eine Kollision ausgelegt sind. Siehe die ursprüngliche Offenlegung der Sicherheitsanfälligkeit . Durch das Versetzen des Hashs durch einen zufälligen Startwert (einmal beim Start festgelegt) können Angreifer nicht mehr vorhersagen, welche Schlüssel kollidieren werden.
Sie können einen festen Startwert festlegen oder die Funktion deaktivieren, indem Sie die PYTHONHASHSEED
Umgebungsvariable festlegen . Die Standardeinstellung ist, random
aber Sie können einen festen positiven ganzzahligen Wert festlegen, 0
indem Sie die Funktion vollständig deaktivieren.
In den Python-Versionen 2.7 und 3.2 ist die Funktion standardmäßig deaktiviert (verwenden Sie den -R
Schalter oder die Einstellung PYTHONHASHSEED=random
, um sie zu aktivieren). Es ist standardmäßig in Python 3.3 und höher aktiviert.
Wenn Sie sich auf die Reihenfolge der Schlüssel in einem Python-Set verlassen haben, tun Sie dies nicht. Python verwendet eine Hash-Tabelle, um diese Typen zu implementieren. Ihre Reihenfolge hängt vom Einfüge- und Löschverlauf ab sowie vom zufälligen Hash-Startwert ab. Beachten Sie, dass dies in Python 3.5 und älter auch für Wörterbücher gilt.
Siehe auch die object.__hash__()
spezielle Methodendokumentation :
Hinweis : Standardmäßig werden die __hash__()
Werte von str-, bytes- und datetime-Objekten mit einem unvorhersehbaren Zufallswert "gesalzen". Obwohl sie innerhalb eines einzelnen Python-Prozesses konstant bleiben, sind sie zwischen wiederholten Aufrufen von Python nicht vorhersehbar.
Dies soll Schutz vor einem Denial-of-Service bieten, der durch sorgfältig ausgewählte Eingaben verursacht wird, die die Worst-Case-Leistung einer Dikt-Einfügung, O (n ^ 2) -Komplexität, ausnutzen. Siehe http://www.ocert.org/advisories/ocert-2011-003.html Informationen finden .
Das Ändern von Hash-Werten wirkt sich auf die Iterationsreihenfolge von Diktaten, Mengen und anderen Zuordnungen aus. Python hat niemals Garantien für diese Reihenfolge gegeben (und sie variiert normalerweise zwischen 32-Bit- und 64-Bit-Builds).
Siehe auch PYTHONHASHSEED
.
Wenn Sie eine stabile Hash-Implementierung benötigen, sollten Sie sich wahrscheinlich das hashlib
Modul ansehen . Dies implementiert kryptografische Hash-Funktionen. Das Pybloom-Projekt verwendet diesen Ansatz .
Da der Offset aus einem Präfix und einem Suffix (Startwert bzw. endgültiger XOR-Wert) besteht, können Sie den Offset leider nicht einfach speichern. Auf der positiven Seite bedeutet dies, dass Angreifer den Versatz mit Timing-Angriffen auch nicht einfach bestimmen können.
disable
wenn es auf 0 gesetzt wird? Ich sehe keinen effektiven Unterschied darin, eine alte stabile Startnummer festzulegen, es sei denn, mir fehlt etwas. Was ich meine ist, wenn ich benutze,PYTHONHASHSEED=12345
bekomme ich den gleichen Hash für gleiche Zeichenfolgen auch über Sitzungen hinweg - das gleiche passiert, wenn ich benutzePYTHONHASHSEED=0
- der Hash für gleiche Zeichenfolgen ist über Sitzungen hinweg gleich (wenn auch anders als 12345, aber das ist offensichtlich, so sind Seeds Arbeit).0
da es überhaupt keinen Startwert gibt und die Hashes für Objekte denen entsprechen, die in einer älteren Python-Version ohne Hashseed-Unterstützung generiert wurden.Die Hash-Randomisierung ist in Python 3 standardmäßig aktiviert . Dies ist ein Sicherheitsmerkmal:
In früheren Versionen von 2.6.8 konnten Sie es in der Befehlszeile mit -R oder der Umgebungsoption PYTHONHASHSEED aktivieren .
Sie können es ausschalten, indem Sie es
PYTHONHASHSEED
auf Null setzen.quelle
hash () ist eine in Python integrierte Funktion , mit der ein Hashwert für ein Objekt berechnet wird , nicht für einen String oder eine Nummer.
Sie können die Details auf dieser Seite sehen: https://docs.python.org/3.3/library/functions.html#hash .
und hash () -Werte stammen aus der __hash__- Methode des Objekts. Der Arzt sagt Folgendes:
Aus diesem Grund haben Sie einen unterschiedlichen Hashwert für dieselbe Zeichenfolge in einer anderen Konsole.
Was Sie implementieren, ist kein guter Weg.
Wenn Sie einen String-Hash-Wert berechnen möchten, verwenden Sie einfach hashlib
hash () zielt darauf ab, einen Objekt-Hash-Wert zu erhalten, keinen stirng.
quelle
hash()
ist perfekt gültig für Zeichenfolgen oder numerische Werte. Sie sind verwirrend dies mit der__hash__
benutzerdefinierten Methode verwendet durchhash()
eine benutzerdefinierte Implementierung des Hash - Wertes zu liefern.