Wie generieren Sie Zeichenketten, die den gleichen Hashcode in Java teilen?

9

Ein vorhandenes System, das in Java geschrieben ist, verwendet den Hashcode einer Zeichenfolge als Routing-Strategie für den Lastenausgleich.

Nun kann ich das System nicht ändern , muss jedoch Zeichenfolgen generieren, die denselben Hashcode verwenden, um die schlechteste Bedingung zu testen.

Ich gebe diese Zeichenfolgen von der Befehlszeile aus und hoffe, dass das System alle diese Zeichenfolgen an dasselbe Ziel weiterleitet.

Ist es möglich, eine große Anzahl von Strings zu generieren, die denselben Hashcode haben?

Um diese Frage klarzustellen:

%Vor%

Anmerkungen: Jeder hashCode-Wert ist akzeptabel. Es gibt keine Einschränkung für die Zeichenfolge. Aber sie sollten sich voneinander unterscheiden.

BEARBEITEN: Override-Methode der String-Klasse ist nicht akzeptabel, da ich diese Zeichenfolge von der Befehlszeile aus füttere.

Die Instrumentierung ist auch nicht akzeptabel, da dies einige Auswirkungen auf das System haben wird.

    
StarPinkER 17.10.2012, 01:51
quelle

5 Antworten

19

Da du chinesisch lesen kannst, kannst du meinen Beitrag ansehen Ссылка

sehen Sie eine Testmethode im Grunde, solange Sie übereinstimmen, a1 * 31 + b1 = a2 * 31 + b2, was bedeutet (a1-a2) * 31 = b2-b1

%Vor%

Sie werden

erhalten %Vor%

edit: Jemand hat gesagt, das ist nicht einfach genug. Ich habe unten Teil

hinzugefügt %Vor%

unten ist der Quellcode, es könnte nicht effizient sein, aber es funktioniert:

%Vor%

Sehen Sie sich String.hashCode () an

%Vor%     
hetaoblog 17.10.2012, 02:36
quelle
5

Ich finde, dass eine Hash-Zeichenfolge, die aus einer langen Zeichenfolge besteht, zu hart ist. Es ist einfach, wenn Sie eine Hash-Zeichenfolge einer kurzen Zeichenfolge (2 oder 3) finden. Schau dir die Gleichung unten an. (Entschuldigung, ich kann Bild nicht veröffentlichen, verursacht mir neues Mitglied)

Beachten Sie, dass "FB" und "Ea" den gleichen Hashcode haben, und alle zwei Strings wie s1 + "FB" + s2 und s1 + "Ea" + s2 haben den gleichen Hashcode. Die einfache Lösung besteht also darin, eine 2-char-Teilzeichenkette der bestehenden Zeichenkette zu finden und durch eine 2-Zeichenkette-Teilzeichenkette mit demselben Hashcode zu ersetzen

Beispiel, wir haben die Zeichenfolge "helloworld" hole 2-char-Teilzeichenfolge "he", hashcode ("he") = 'h' * 31 + 'e' = ('h' * 31 + 31) + ('e' - 31) = ('h' + 1 ) * 31 + 'F' = 'i' + 'F' = Hashcode ("iF") also ist die Wunschschnur "iFloworld" Wir haben 'h' um 1 erhöht, wir können um 2, oder 3 usw. erhöhen (aber es wird falsch sein, wenn es den char-Wert überschreitet)

Der unten stehende Code läuft gut mit kleinen Level, es wird falsch wenn der Level groß ist, mache den Char Wert überlaufen, ich werde es später reparieren wenn du willst (dieser Code ändert 2 erste Zeichen, aber ich werde Code auf 2 bearbeiten letzte Zeichen, weil 2 erste Zeichen mit dem größten Wert berechnet werden)

%Vor%     
yelliver 17.10.2012 02:48
quelle
1

Sie können die java.lang.String-Klasse so instrumentieren, dass ihre Methode hashCode () immer die gleiche Zahl zurückgibt.

Ich nehme an, dass der Javassist der einfachste Weg ist, eine solche Instrumentierung durchzuführen.

Kurz gesagt:

  • Erhalte eine Instanz von java.lang.instrument.Instrumentation mit einem Java-Agenten (siehe package java.lang.instrument Dokumentation für Details)
  • Definieren Sie die java.lang.String-Klasse neu, indem Sie die Methode Instrumentation.redefineClasses (ClassDefinition [])
  • verwenden

Der Code sieht ungefähr so ​​aus:

%Vor%

Vergessen Sie auch nicht, dass die Agent-Manifestdatei Can-Redefine-Classes: true angeben muss, um die redefineClasses-Methode (ClassDefinition []) verwenden zu können.

    
Male 17.10.2012 02:08
quelle
1

Ich habe mich gefragt, ob es eine "universelle" Lösung gibt; z.B. eine konstante Zeichenfolge XYZ , so dass

%Vor%

für eine beliebige Zeichenfolge s . Das Finden einer solchen Zeichenfolge beinhaltet das Lösen einer ziemlich komplizierten Gleichung ... die jenseits meiner rostigen mathematischen Fähigkeit lag. Aber dann dämmerte es mir, dass h == 31*h + ch immer true ist, wenn h und ch beide null sind!

Basierend auf dieser Erkenntnis sollte die folgende Methode einen anderen String mit demselben Hashcode wie sein Argument erstellen:

%Vor%

Wenn NUL-Zeichen für Sie problematisch sind, würde die vorangestellte beliebige Zeichenkette, deren Hashcode Null ist, auch funktionieren ... obwohl die kollidierenden Zeichenketten länger wären, als wenn Sie Null verwenden würden.

    
Stephen C 17.10.2012 03:15
quelle
0
%Vor%

Funktioniert das für Sie? Es erstellt nur eine Menge Kopien desselben String-Literals, die Sie dann in Ihren Tests verwenden können.

    
Code-Apprentice 17.10.2012 02:04
quelle

Tags und Links