Ist es überall in der Dokumentation garantiert, dass Hashes mit gleichen Schlüsseln auch dieselbe Reihenfolge haben?

8

Es gibt nicht viele Garantien über die Reihenfolge der Hash-Schlüssel in Perl. Gibt es eine Erwähnung in Dokumenten, die ich nicht finden kann, die sagen würde, dass, solange zwei Hashes genau dieselben Schlüssel verwenden, sie in genau derselben Reihenfolge gehen werden?

Kurzer Test scheint das zu bestätigen. Selbst wenn ich einige zusätzliche Schlüssel für die interne Schlüsseltabelle zwischen zwei verschiedenen Hashes erzeuge, werden ihre Schlüssel in der gleichen Reihenfolge zurückgegeben:

%Vor%

Ich würde mich jedoch nicht auf udokumentiertes Verhalten verlassen, und Tatsache, die einfach in Dokumenten gefunden werden kann, ist, dass keys , values und each alle dieselbe Reihenfolge verwenden, solange Hash nicht geändert wird.

    
Oleg V. Volkov 04.10.2012, 09:18
quelle

6 Antworten

0

Seit mindestens 5.18 wird das folgende explizit in perldoc perlsec erwähnt:

  

keys , values und each geben Elemente in einer per Hash-Zufallsreihenfolge zurück.   Durch das Ändern eines Hashs durch Einfügen wird die Iterationsreihenfolge geändert   Hash.

  

Perl hat niemals eine Reihenfolge der Hash-Schlüssel garantiert, und der   Die Bestellung hat sich während der Laufzeit von Perl bereits mehrfach geändert   5. Die Reihenfolge der Hash-Schlüssel war und ist auch immer von der Reihenfolge der Anzeigen und der Historie der vorgenommenen Änderungen abhängig   der Hash während seiner Lebensdauer.

Daher ist es NICHT garantiert, dass zwei Hashes mit demselben Schlüsselsatz in der gleichen Reihenfolge iteriert werden.

    
Oleg V. Volkov 24.04.2017, 11:04
quelle
13

Von Perlsec:

  

Perl hat niemals die Reihenfolge der Hash-Schlüssel garantiert und der   Die Bestellung hat sich während der Laufzeit von Perl bereits mehrfach geändert   5. Auch die Reihenfolge der Hash-Schlüssel war und ist immer von der Reihenfolge der Anzeigen betroffen.

Ссылка

    
matt freake 04.10.2012 09:25
quelle
7
___ answer12732963 ___

Es wird ausdrücklich garantiert, dass dies unzuverlässig ist.

Weitere Informationen finden Sie im Abschnitt Algorithmic Complexity Attacks von qw(a b c d e f) . Trotz seiner bedauerlichen Inkohärenz heißt es:

  • in 5.8.1 ist die Reihenfolge garantiert immer zufällig.
  • in 5.8.2 und später wird die Reihenfolge identisch sein, es sei denn, Perl erkennt pathologisches Verhalten (insbesondere eine Reihe von Schlüsseln, die alle auf eine kleine Anzahl von Buckets hashen würden, wodurch die Hash-Leistung leidet). In diesen Fällen ist "die Funktion durch einen Pseudozufallssamen gestört".

Die Dokumentation garantiert nicht , dass die Reihenfolge immer gleich ist; In der Tat heißt es ausdrücklich, dass es in einem pathologischen Fall nicht vorhersagbar sein wird. Sollte die Hashing-Funktion in einer zukünftigen Version geändert werden, ist es möglich, dass Daten, die bisher kein degeneriertes Hashing erzeugt haben, dies nun tun würden und dann der zufälligen Störung unterliegen würden.

Wenn Sie also nicht 5.8.1, vielleicht verwenden, erhalten Sie die gleiche Reihenfolge, und vielleicht ändert sich das bei Ihnen nicht Aktualisieren Sie Ihre Perl, aber es könnte. Wenn Sie 5.8.1 verwenden, ist eine zufällige Reihenfolge garantiert .

Wenn Sie eine zuverlässige Reihenfolge wünschen, verwenden Sie eine der CPAN-Klassen, die einen Hash mit einer garantierten Schlüsselreihenfolge bereitstellen - Tie :: Hash :: Indiziert , Tie :: IxHash - oder sortiere einfach deine Schlüssel. Wenn Sie einen Hashwert mit weniger als ein paar tausend Schlüsseln haben, werden Sie wahrscheinlich keinen nennenswerten Unterschied bemerken. Wenn es mehr als das hat, sollten Sie vielleicht eine schwerere Lösung wie eine Datenbank in Erwägung ziehen.

Edit: und nur um es interessanter zu machen, werden Schlüssel zufällig nach 5.18 geordnet .

    
___ answer12731481 ___

Hier ist ein Gegenbeispiel, das kürzer ist als (anscheinend habe ich seine Antwort verpasst, als ich es zum ersten Mal gesehen habe.)

diese Frage):

%Vor%

Ausgabe:

%Vor%     
___ answer12724176 ___

perldoc -f-Schlüssel enthält einige Informationen zur Bestellung:

  

Die Schlüssel eines Hash werden in einer scheinbar zufälligen Reihenfolge zurückgegeben. Die tatsächliche zufällige Reihenfolge kann in zukünftigen Versionen von Perl geändert werden, aber es ist garantiert, dass sie der Reihenfolge entspricht, in der die Werte oder jede Funktion erzeugt wird (vorausgesetzt, der Hash wurde nicht geändert). Seit Perl 5.8.1 kann die Reihenfolge selbst zwischen verschiedenen Perl-Ausführungen aus Sicherheitsgründen anders sein (siehe Algorithmische Komplexitätsangriffe in Perlsec).

Die einzige Garantie ist, dass keine Bestellung garantiert ist.

    
___ answer43586397 ___

Seit mindestens 5.18 wird das folgende explizit in perldoc perlsec erwähnt:

  

%code% , %code% und %code% geben Elemente in einer per Hash-Zufallsreihenfolge zurück.   Durch das Ändern eines Hashs durch Einfügen wird die Iterationsreihenfolge geändert   Hash.

  

Perl hat niemals eine Reihenfolge der Hash-Schlüssel garantiert, und der   Die Bestellung hat sich während der Laufzeit von Perl bereits mehrfach geändert   5. Die Reihenfolge der Hash-Schlüssel war und ist auch immer von der Reihenfolge der Anzeigen und der Historie der vorgenommenen Änderungen abhängig   der Hash während seiner Lebensdauer.

Daher ist es NICHT garantiert, dass zwei Hashes mit demselben Schlüsselsatz in der gleichen Reihenfolge iteriert werden.

    
___ qstnhdr ___ Ist es überall in der Dokumentation garantiert, dass Hashes mit gleichen Schlüsseln auch dieselbe Reihenfolge haben? ___ tag123hash ___ Eine Hash-Funktion ist eine wohldefinierte Prozedur oder mathematische Funktion, die eine große Datenmenge in ein kleines Datum umwandelt, normalerweise eine ganze Zahl. Bei Fragen zum Twitter- und Facebook-Symbol verwenden Sie den Hashtag. Verwenden Sie bei Fragen zu URLs und HTML-Ankern die Fragment-ID. Bei Fragen zu Rubys Hash-Typ verwenden Sie Ruby-Hash. ___ tag123perl ___ Perl ist eine prozedurale, allgemeine Programmiersprache für allgemeine Zwecke, die für ihre native Unterstützung von regulären Ausdrücken und String-Parsing-Funktionen bekannt ist. Bitte verwenden Sie diesen Tag für Fragen zu Perl im Allgemeinen. Für Dinge, die mit der neuen (aber verwandten) Sprache "Perl 6" zu tun haben, verwenden Sie bitte das perl6-Tag. Verwenden Sie für reguläre Ausdrücke nach Perl-Art in anderen Sprachen das Regex-Tag oder, falls sie auf der PCRE-Bibliothek basieren, das PCRE-Tag. ___ qstntxt ___

Es gibt nicht viele Garantien über die Reihenfolge der Hash-Schlüssel in Perl. Gibt es eine Erwähnung in Dokumenten, die ich nicht finden kann, die sagen würde, dass, solange zwei Hashes genau dieselben Schlüssel verwenden, sie in genau derselben Reihenfolge gehen werden?

Kurzer Test scheint das zu bestätigen. Selbst wenn ich einige zusätzliche Schlüssel für die interne Schlüsseltabelle zwischen zwei verschiedenen Hashes erzeuge, werden ihre Schlüssel in der gleichen Reihenfolge zurückgegeben:

%Vor%

Ich würde mich jedoch nicht auf udokumentiertes Verhalten verlassen, und Tatsache, die einfach in Dokumenten gefunden werden kann, ist, dass %code% , %code% und %code% alle dieselbe Reihenfolge verwenden, solange Hash nicht geändert wird.

    
___ answer12724181 ___

Von Perlsec:

  

Perl hat niemals die Reihenfolge der Hash-Schlüssel garantiert und der   Die Bestellung hat sich während der Laufzeit von Perl bereits mehrfach geändert   5. Auch die Reihenfolge der Hash-Schlüssel war und ist immer von der Reihenfolge der Anzeigen betroffen.

Ссылка

    
___
pilcrow 04.10.2012 14:58
quelle
5

Es wird ausdrücklich garantiert, dass dies unzuverlässig ist.

Weitere Informationen finden Sie im Abschnitt Algorithmic Complexity Attacks von perlsec . Trotz seiner bedauerlichen Inkohärenz heißt es:

  • in 5.8.1 ist die Reihenfolge garantiert immer zufällig.
  • in 5.8.2 und später wird die Reihenfolge identisch sein, es sei denn, Perl erkennt pathologisches Verhalten (insbesondere eine Reihe von Schlüsseln, die alle auf eine kleine Anzahl von Buckets hashen würden, wodurch die Hash-Leistung leidet). In diesen Fällen ist "die Funktion durch einen Pseudozufallssamen gestört".

Die Dokumentation garantiert nicht , dass die Reihenfolge immer gleich ist; In der Tat heißt es ausdrücklich, dass es in einem pathologischen Fall nicht vorhersagbar sein wird. Sollte die Hashing-Funktion in einer zukünftigen Version geändert werden, ist es möglich, dass Daten, die bisher kein degeneriertes Hashing erzeugt haben, dies nun tun würden und dann der zufälligen Störung unterliegen würden.

Wenn Sie also nicht 5.8.1, vielleicht verwenden, erhalten Sie die gleiche Reihenfolge, und vielleicht ändert sich das bei Ihnen nicht Aktualisieren Sie Ihre Perl, aber es könnte. Wenn Sie 5.8.1 verwenden, ist eine zufällige Reihenfolge garantiert .

Wenn Sie eine zuverlässige Reihenfolge wünschen, verwenden Sie eine der CPAN-Klassen, die einen Hash mit einer garantierten Schlüsselreihenfolge bereitstellen - Tie :: Hash :: Indiziert , Tie :: IxHash - oder sortiere einfach deine Schlüssel. Wenn Sie einen Hashwert mit weniger als ein paar tausend Schlüsseln haben, werden Sie wahrscheinlich keinen nennenswerten Unterschied bemerken. Wenn es mehr als das hat, sollten Sie vielleicht eine schwerere Lösung wie eine Datenbank in Erwägung ziehen.

Edit: und nur um es interessanter zu machen, werden Schlüssel zufällig nach 5.18 geordnet .

    
Joe McMahon 04.10.2012 17:55
quelle
4

Hier ist ein Gegenbeispiel, das kürzer ist als (anscheinend habe ich seine Antwort verpasst, als ich es zum ersten Mal gesehen habe.)

diese Frage):

%Vor%

Ausgabe:

%Vor%     
Sinan Ünür 04.10.2012 16:17
quelle
3

perldoc -f-Schlüssel enthält einige Informationen zur Bestellung:

  

Die Schlüssel eines Hash werden in einer scheinbar zufälligen Reihenfolge zurückgegeben. Die tatsächliche zufällige Reihenfolge kann in zukünftigen Versionen von Perl geändert werden, aber es ist garantiert, dass sie der Reihenfolge entspricht, in der die Werte oder jede Funktion erzeugt wird (vorausgesetzt, der Hash wurde nicht geändert). Seit Perl 5.8.1 kann die Reihenfolge selbst zwischen verschiedenen Perl-Ausführungen aus Sicherheitsgründen anders sein (siehe Algorithmische Komplexitätsangriffe in Perlsec).

Die einzige Garantie ist, dass keine Bestellung garantiert ist.

    
amon 04.10.2012 09:24
quelle

Tags und Links