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.
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%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%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:
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.
Ich habe mich gefragt, ob es eine "universelle" Lösung gibt; z.B. eine konstante Zeichenfolge XYZ
, so dass
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.
Funktioniert das für Sie? Es erstellt nur eine Menge Kopien desselben String-Literals, die Sie dann in Ihren Tests verwenden können.