Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Rechnen mit Buchstaben und Zahlen
walter_b - Sa 12.07.08 18:22
Titel: Rechnen mit Buchstaben und Zahlen
Hallo zusammen.
Ist es möglich, mit einem 36er-Zahlensystem zu rechnen? Also dass es nach 9 einfach mit a, b, c etc. weitergeht? Z.b.
Quelltext
1:
| a56b8e7uzx + 1 = a56b8e7uzy |
Dass es mit Hexidezimal möglich ist, habe ich bereits herausgefunden, doch wie siehts mit dem aus? Falls ja, wie müsste ich das anstellen?
Vielen Dank für eure Hilfe.
nagel - Sa 12.07.08 18:34
Einfach für Berechnungen in "normale" Zahlen konvertieren und zur Ausgabe wieder zurück.
walter_b - Sa 12.07.08 18:38
Das ganze wird dann aber ziemlich langsam, wenn immer jede Stelle einzel berechnet werden muss, nicht? Das Ziel ist eben, dass dies schnell vonstatten geht, seeehr schnell ;)
nagel - Sa 12.07.08 18:45
Ich weiß ja nicht genau, was du vorhast, aber vermutlich sollen die Zahlen im 36er-System ein- und ausgegeben werden und zwischendurch diverse Berechnungen durchlaufen. Was ich vorher sagen wollte, ist, dass du einfach zwei Funktionen zur Konvertierung von 36er-System-Strings in Integers und zurück schreibst und deine Zahlen intern dann eben als Integers speicherst und verrechnest. Die Umrechnung wird auch nicht so aufwendig, dass das langsam wäre.
Hidden - Sa 12.07.08 19:06
Inter wird ja im Binärsystem gerechnet; Zahlen werden vom 10er ins 2er-System konvertiert. Warum sollte man denn nun den Gegenteiligen weg gehen und die Basis vergrößern? Das Binärsystem scheint ja Vorteile zu haben..
Und wenn, warum dann ausgerechnet 0..9 + a..z; das läge ja nur an unseren Zeichen. Eine noch größere Basis würde einen möglichen Vorteil ja potenzieren!
Meine Glaskugel(ja, die benutze ich jetz auch mal ;)) sagt mir, dass du entweder größere Zahlen als mit Integer darstellen willst(
INT64,
BININT) oder Eingaben in hexadezimaler Notation zulassen willst. Dazu gigbt es bestimmt analog zu IntToStr und StrToINt ähnliche Funktionen mit HexToStr und StrToHex..
mfG,
Timosch - Sa 12.07.08 19:07
Auf dsdt findet man das hier:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| function DezToX(dez, bas: Cardinal): String; const zahlen: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); begin If (Bas>16) OR (bas<2) Then Begin MessageDlg('Unzulässige Zahlenbasis:'+IntToStr(bas),mtWarning,[mbOK],0); Abort; End; if dez <> 0 then Result := DezToX(dez div bas, bas) + zahlen[dez mod bas] else Result := ''; end; |
Geht aber leider nur von Basis 2 bis 16, aber du kannsts ja umschreiben.
walter_b - Sa 12.07.08 19:17
Vielen Dank für eure Bemühungen. Um vorerst einmal die Schummelei der Glaskugel aufzudecken: Ich habe was ganz anderes vor. Und zwar (haltet euch fest ;) ): ich will simulieren, wie ein Passwortknackprogramm funktioniert. Und deshalb würde ich gerne einfach die ganzen Kombinationen (Bruteforce) durchgehen. Das mit den 36 war einmal eine Grundstufe, würde a-z und 0-9 entsprechen, jedoch könnte ich das ja dann noch auf A-Z und ev. sogar Sonderzeichen aufstocken. Da ich dann auch noch die Simulationsgeschwindigkeit mit einer herkömmlichen Knackgeschwindigkeit vergleichen will, wäre es natürlich toll, wenn nicht allzu grosser Rechenaufwand dahinter steckt, damit mein Programm einigermassen mithalten kann. Oder ist es unmöglich, an die Knackgeschwindigkeit von John the Ripper oder ähnlichem (um die 4'000'000 Keys pro Sekunde) ranzukommen?
nagel - Sa 12.07.08 19:46
Und wo ist da ein anderes Zahlensystem von Nöten? :?!?:
walter_b - Sa 12.07.08 20:03
Da ich ja von der einen Kombination zur nächsten kommen will, wäre es noch praktisch, wenn ich einfach +1 rechnen könnte. Oder wie würdest du das machen? Einfach mal ein paar Milliarden Kombinationen in einen Array speichern?
Timosch - Sa 12.07.08 20:13
Dazu sind absolut keine Buchstaben vonnöten. Behandle die Buchstaben als Zahlen und prüfe von 0 bis 255, dann hast du das gesamte ANSI-System abgedeckt (bei Unicode ist es entsprechend dann 65536).
walter_b - Sa 12.07.08 21:39
War kurz afk... ;)
hm... Etwas in diese Richtung habe ich mir auch schon überlegt. Würdest du dann jede Stelle einzeln behandeln? Oder ist es möglich, alles in eines zu packen?
Jerk - So 13.07.08 00:17
edit Vergesst diesen Post :p
Hidden - So 13.07.08 00:39
Hi,
Edit: Okay, vergessen^^ /Edit
Ich würd das rekuriv machen: Die Prozedur löst sich in einer repeat-Schleife(schneller als for) für jeden Char(i := #0-> #255) einmal selbst aus(Rekursion) und hängt immer idesen Char an. So werden alle Möglichkeiten durchlaufen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| type TPWLaenge = 0..12; procedure GeneriereKombinationen(const aRekursion: TPWLaenge; const aPasswort: String): Boolean; var i: Char; begin i := #0; if aRekursion <> 0 then begin repeat Inc(i); result := GeneriereKombinationen(Pred(aRekursion), aPasswort + i); until i = #255; end else begin repeat Inc(i); result := ProbiereAus(aPasswort + i); until i = #255; end; end;
procedure KnackePasswort(); var i: Integer; begin for i := 0 to 12 do begin if GeneriereKombinationen(i, '') then break; end; end; |
So, eine Sache noch: Wahrscheinlich lohnt es sich, zuerst einen eingeschränkten Zeichensatz zu durchlaufen, da die meißten PWs nur ein bestimmtes Set verwenden..
mfG,
Jerk - So 13.07.08 01:12
Ist nich die Anzahl an Kombinationen gleich der Anzahl möglicher Zeichen hoch Länge des Passwordes?
Also wenn man nur im bereich 1 bis 128 bleibt, hat man 128^2 also 16384 Kombinationen ?
Hab mal was zusammen gebastelt was glaube ich alle kombinationen ermittelt:
Konnte bei Google spontan nix finden, falls es irgentwie schneller geht, und das glaube ich, würde ich gerne wissen wie.
Knappe zwei Sekundne für 16384 Kombinationen ist nicht wirklich gut!
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| var Jump : Integer; Str : String; StPos : Integer; pwLength : Integer; Spectrum : Integer; CombList : TStringList; ... procedure TBruteForcer.GenerateCombinations; var i : integer; begin StPos := 0; Str := ''; for i := 1 to pwLength do Str:=Str + chr(1); CombList.Add(Str); Step; end; procedure TBruteForcer.Step; begin inc(Stpos,1); jump := 0; Compare; CombList.Add(Str); if StPos < power(Spectrum,pwLength)-1 then Step; end; procedure TBruteForcer.Compare; begin if ord(Str[pwLength-jump]) < Spectrum then Str[pwLength-jump]:=chr(ord(Str[pwLength-jump])+1) else if jump < pwLength then begin Str[pwLength-jump]:=chr(1); inc(jump,1); Str[pwLength-jump]:=chr(ord(Str[pwLength-jump])+1); Compare; end; end; |
;
walter_b - So 13.07.08 09:37
Jerk hat folgendes geschrieben: |
Ist nich die Anzahl an Kombinationen gleich der Anzahl möglicher Zeichen hoch Länge des Passwordes?
Also wenn man nur im bereich 1 bis 128 bleibt, hat man 128^2 also 16384 Kombinationen ?
[...]
Knappe zwei Sekundne für 16384 Kombinationen ist nicht wirklich gut! |
Das mit der Anzahl möglicher Kombinationen stimmt. Aber irgendwie wäre es vielleicht noch praktisch, wenn er nicht einfach alle Möglichkeiten durchgeht, sondern man allenfalls während des Rechnungsprozesses auch noch rausfinden könnte, wo er gerade steht.
Und ja, die Geschwindigkeit, die du erreicht hast, ist zwar ganz nett, aber trotzdem noch ein bisschen zu langsam ;)
Aber ich frage mich sowieso, wie John the Ripper die 4 Mios hinbringt. Schliesslich geht er jede Möglichkeit durch, während dem laufenden Prozess kann man durch drücken einer beliebigen Taste die aktuelle Position sowie die Geschwindigkeit innerhalb von weniger als 0.5 Sekunden abrufen. Damit er nur schon die Geschwindigkeit weiss, mit welcher er unterwegs ist, die Systemzeit und alles auch immernoch aufzeichnet und sogar ein Logbuch führt braucht er wohl einiges an Rechenleistung nur schon für die "Umgebung". Ist das überhaupt möglich, eine annährend gleich schnelle Simulation zu erstellen?
Ich werde jetzt mal noch die Lösung von Hidden genauer anschauen, da mir auf den ersten Blick nicht gerade klar wurde, wie das ganze funktioniert.
Aber auf jeden Fall schon mal vielen Dank für eure Codesamples und eure Bemühungen.
Edith meint noch: Jungs, ihr seid viel zu grosszügig mit den Zeichen. Wird bei JTR "all" ausgewählt, so kommen 95 verschiedene Zeichen dran. Und wenn ihr euch das mal für ein normales Passwort überlegt: a-z, A-Z, 0-9. Damit hat man erst 62 Zeichen. Von daher würde ich eher auf eine Länge von 95 als auf 255 setzen, aber dies ist ja nur ein kleines Detail. Vielleicht hilfts ja. Habe gerade auch noch eine Idee, werde dies nachher gleich noch ausprobieren.
walter_b - So 13.07.08 11:26
Ich habe jetzt bei mir auchmal was ausprobiert. Lasse ich einfach nur die Zahlen durchzählen, macht meiner ungefähr 100'000'000 pro Sekunde. Jedoch ist ja nicht das Ziel, einfach durchzuzählen. Deshalb habe ich folgenden Programmteil versucht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| var combs : Comp; digits : integer; characters : integer; position : int64; rest : integer; count : integer; limit : integer; DateTime1 : TDateTime; DateTime2 : TDateTime; Ziit : Comp;
begin
write('Anzahl Kombinationen: ');readln(combs); DateTime1 := Time; position:=0; count:=0; limit:=(characters+1)*100; rest:=100-characters; repeat repeat repeat inc(count); inc(position); until count = characters; inc(position,rest); count:=0; until position = limit; inc(position,((rest-1)*100)); until position = combs; writeln(combs); DateTime2 := Time; ziit := DateTime2-DateTime1; writeln(ziit); readln; end. |
Die Idee dahinter ist relativ simpel: Ich nehme an, dass jeweils zwei Stellen in der Zahl einer Stelle im Passwort entspricht. Da das Passwort jedoch nur 95 Zeichen und nicht 100, wie die Zahl, hat, muss natürlich ein bisschen rumgebastelt werden. Diese Programm ist noch nicht fertig, doch schon bei 20'000 Kombinationen braucht es enorm lange. Ich weiss zwar nicht, was ich falsch mache, oder ob es wirklich so schlecht programmiert ist.
Vielleicht kann ja einer von euch mit der Idee was anfangen oder bringt einen besseren Vorschlag.
Vielen Dank im Voraus.
Hidden - So 13.07.08 11:39
walter_b hat folgendes geschrieben: |
| Edith meint noch: Jungs, ihr seid viel zu grosszügig mit den Zeichen. Wird bei JTR "all" ausgewählt, so kommen 95 verschiedene Zeichen dran. Und wenn ihr euch das mal für ein normales Passwort überlegt: a-z, A-Z, 0-9. Damit hat man erst 62 Zeichen. Von daher würde ich eher auf eine Länge von 95 als auf 255 setzen, aber dies ist ja nur ein kleines Detail. Vielleicht hilfts ja. Habe gerade auch noch eine Idee, werde dies nachher gleich noch ausprobieren. |
Hidden hat folgendes geschrieben: |
| So, eine Sache noch: Wahrscheinlich lohnt es sich, zuerst einen eingeschränkten Zeichensatz zu durchlaufen, da die meißten PWs nur ein bestimmtes Set verwenden.. |
;)
walter_b - So 13.07.08 11:47
Meine Aussage war nicht für dich bestimmt, aber tut mir leid, dass ich dich wiederholt habe ;)
Ich komme irgendwie nicht weiter. :( Habe hier mal noch einen Code aus der Konfigurationsdatei von JTR:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| int length; // Current length
void init() { word[0] = 'A' - 1; // Start with "A" word[length = 1] = 0; }
void generate() { int i;
i = length - 1; // Start from the last character while (++word[i] > 'Z') // Try to increase it if (i) // Overflow here, any more positions? word[i--] = 'A'; // Yes, move to the left, and repeat else // No if (length < 7) { word[i = ++length] = 0; // Switch to the next length while (i--) word[i] = 'A'; return; } else { word = 0; return; // We're done } }
void restore() { length = 0; // Calculate the length while (word[length]) length++; } |
Hidden - So 13.07.08 12:09
Hi,
Die Idee im letzten Post finde ich genial^^ im Prinzip wird ein Array wie eine Zahlenvariable behandelt. Durch Überlauf verhält es sich auch so.
Mir wurde aber meine ich mal gesagt, dass ein Überlauf verhindert wird, indem die Zahl im Prozessor in sich selbst überläuft oder so :gruebel: vielleicht kann da besser jemand, der sich auskennt was sagen. Außerdem wäre imho noch garnicht gesagt, dass die Arrayelemente im Speicher auch hintereinander liegen(habe es aber auch nur überflogen, bin mir gerade unsicher, ob ich das richtig verstanden habe^^).
Imho müsste man aber garnicht ständig auf Überlauf checken, wenn man mit Pointern arbeitet:
Man nehme eine Cardinal-Variable, lasse sie hochlaufen und arbeite mit Pointern auf ihre einzelnen Bytes, die man in PChar castet.. Nur so ne Idee, hab ich auch noch nicht mit gearbeitet. Vorteil wäre, dass eine normal optimierte Zählvariable dabei läuft. Die könnte man dann noch so gestalten, dass nur die besagten Chars durchlaufen werden('a'..'z', 'A'..'Z', '0'..'9').
mfG,
Jerk - So 13.07.08 12:34
walter_b hat folgendes geschrieben: |
Und ja, die Geschwindigkeit, die du erreicht hast, ist zwar ganz nett, aber trotzdem noch ein bisschen zu langsam ;)
|
Jerk hat folgendes geschrieben: |
Knappe zwei Sekundne für 16384 Kombinationen ist nicht wirklich gut
|
Habe grade rausgefunden das mein Code so lahm, is weil er alles in eine Listbox/Stringlist schreibt. Gibt es ne schnellere Methode?
walter_b - So 13.07.08 12:37
Jerk hat folgendes geschrieben: |
Wäre evtl ein Script für das ganze besser? |
Hm... wie meinst du?
@Hidden: Ich habe bisher noch nie mit Pointern gearbeitet. Habe jetzt ein wenig in der Hilfe nachgelesen, aber habe keine Ahnung, wie ich das ganze Umsetzen sollte. :?
Jerk - So 13.07.08 12:52
Na die ganze rekursion in ein Script auslagen, z.B. Python?!?
GTA-Place - So 13.07.08 13:13
Meine aktuelle Funktion schafft 365.000.000 Kombinationen von A..Z in 1 Sekunde, allerdings ohne jegliche Ausgabe und Stringumwandlung.
Ich poste sie später, muss noch optimieren.
Jerk - So 13.07.08 13:32
Richtig Langsam wird es erst wenn der String ausgegeben wird -.-
Wie messe ich die Zeit am besten um mal zu wissen wie schnell mein Code is?
Tilman - So 13.07.08 14:08
Jerk hat folgendes geschrieben: |
Wie messe ich die Zeit am besten um mal zu wissen wie schnell mein Code is? |
Dazu kannst du SecondsBetween und MillisecondsBetween verwenden.
GTA-Place - So 13.07.08 14:13
Das ist ja noch ungenauer als GetTickCount:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| var Start: Cardinal; begin Start := GetTickCount;
ShowMessage(IntToStr(GetTickCount - Start) + ' ms'); end; |
Tilman - So 13.07.08 14:20
GTA-Place hat folgendes geschrieben: |
Das ist ja noch ungenauer als GetTickCount:
|
warum nicht gleich QueryPerformanceCounter ^^ ich wusste nicht dass es sooo genau sein muss.
walter_b - So 13.07.08 14:57
GTA-Place hat folgendes geschrieben: |
Meine aktuelle Funktion schafft 365.000.000 Kombinationen von A..Z in 1 Sekunde, allerdings ohne jegliche Ausgabe und Stringumwandlung.
Ich poste sie später, muss noch optimieren. |
Schon fertig optimiert? :wink: Klingt nämlich bisher sehr interessant, denn ich habe alleine mit inc(x) nur ungefähr 100'000'000 Kombinationen pro Sekunde erreicht, als ich einfach eine Zahl hochzählen liess, und dies auf einem Quad-Core. Deshalb nähme mich mal wunder, wie dein Skript aussieht. :) Aber lass dich nicht stressen ;)
GTA-Place - So 13.07.08 16:21
Unoptimiert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| procedure Gen(); var X, Y, Len: Integer; Wort: Array[0..10] of Byte; begin Len := 0;
for X := 0 to 10 do Wort[X] := ord('A') - 1;
for X := 0 to 100 do begin Y := 0; inc(Wort[0]);
while Wort[Y] > Ord('Z') do begin inc(Wort[Y + 1]); Wort[Y] := ord('A'); inc(Y);
Len := max(Y, Len); end; end; end; |
EDIT: Optimiert, Stufe 1:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| procedure Gen(); var X, Y, Len: Integer; Wort: Array[0..10] of Char; begin Len := 0;
for X := 0 to 10 do Wort[X] := Chr(Ord('A') - 1);
for X := 0 to 100 do begin Y := 0; inc(Wort[Y]);
while Wort[Y] > 'Z' do begin inc(Wort[Y + 1]); Wort[Y] := 'A'; inc(Y);
Len := max(Y, Len); end; end; end; |
Resultat: 553.000.000 pro Sekunde + Umwandlung von Integer in String nicht mehr nötig.
walter_b - So 13.07.08 16:52
Hast du das ganze in einer Konsolenapplikation gemacht oder worin hast du diesen Code?
Aber sieht gut aus, vielen Dank schon mal!
GTA-Place - So 13.07.08 16:53
Läuft im Fenstermodus ^^
walter_b - So 13.07.08 16:57
GTA-Place hat folgendes geschrieben: |
| Läuft im Fenstermodus ^^ |
Sorry für die Noob-Frage, aber what the heaven ist Fenstermodus? :oops:
GTA-Place - So 13.07.08 16:58
Naja, mit Fenster halt ^^ GUI-Anwendnung, keine Konsole.
Jerk - So 13.07.08 17:59
533 Millionen oder haste ein zwei Nullen zuviel ???
Kannste den Code mal so hier reinpacken das jede einzelne Kombination ausgegeben wird?
walter_b - So 13.07.08 18:07
GTA-Place hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| procedure Gen(); var X, Y, Len: Integer; Wort: Array[0..10] of Char; begin Len := 0;
for X := 0 to 10 do Wort[X] := Chr(Ord('A') - 1);
for X := 0 to 100 do begin Y := 0; inc(Wort[Y]);
while Wort[Y] > 'Z' do begin inc(Wort[Y + 1]); Wort[Y] := 'A'; inc(Y);
Len := max(Y, Len); end; end; end; |
|
Ich würde da gerne mal ein bisschen nachfragen, falls ich darf :) Und zwar ist mir hier nicht alles ganz klar.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| procedure Gen(); var X, Y, Len: Integer; Wort: Array[0..10] of Char; begin Len := 0;
for X := 0 to 10 do Wort[X] := Chr(Ord('A') - 1); for X := 0 to 100 do begin Y := 0; inc(Wort[Y]); while Wort[Y] > 'Z' do begin inc(Wort[Y + 1]); Wort[Y] := 'A'; inc(Y);
Len := max(Y, Len); end; end; end; |
Ich wäre dir sehr dankbar, wenn du meine angefügten Kommentare bestätigen/ beantworten könntest. :) vielen Dank.
GTA-Place - So 13.07.08 19:12
Jerk hat folgendes geschrieben: |
| 533 Millionen oder haste ein zwei Nullen zuviel ??? |
533 Millionen ohne Textausgabe.
Weil gleich ein inc(); folgt. Wäre der Buchstabe jetzt schon A, dann würden wir immer mit B beginnen.
Du kannst es auch 1.000 oder 10.000 oder eben 533 Millionen mal ausführen. Je nachdem wie viele Kombinationen du haben willst :)
Nicht das Array wird erhöht, sondern ein einzelnes Item und in diesem Falle ein Char. inc(A) = B. Intern wird einfach der Ord-Wert um 1 erhöht.
Wenn sein Ord()-Wert größer ist. Delphi rechnet das intern sowieso um.
Um den Buchstaben wieder auf A zu setzen: nach Z folgt A
A; AZ -> B
A; ...
Falls wir die Werte ausgeben wollen
Einfach das for dem end; der Y-Schleife einfügen, dann haben wir die Ausgabe:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| Tmp := ''; for X := Len downto 0 do Tmp := Tmp + Wort[X];
Form1.Memo1.Lines.Add(Tmp); |
Jerk - So 13.07.08 19:39
edit ich gebs auf, verdammter Stackoverflow bei zu langem Pw -.-
walter_b - So 13.07.08 19:55
@GTA-Place: Cool, echt toll das Programm. Vielen Dank! :beer: :zustimm:
GTA-Place - So 13.07.08 20:16
Nochmal optimiert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| procedure Gen(); var X, Y: Integer; Wort: String; fChar: PChar; begin SetLength(Wort, 1); fChar := @Wort[1]; fChar^ := Chr(Ord('A') - 1);
for X := 0 to 100 do begin Y := 1; inc(fChar^); while Wort[Y] > 'Z' do begin inc(Y);
if Y > Length(Wort) then begin SetLength(Wort, Y); Wort[Y] := 'A'; end else inc(Wort[Y]);
Wort[Y - 1] := 'A'; end; end; end; |
Zwar
nur noch 500 Millionen Kombinationen pro Sekunde, aber direkt als String. Du kannst mit Wort weiterarbeiten wie du willst.
GTA-Place - Do 17.07.08 18:06
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| function Gen(); var X, Y: Integer; Signs: Array of Char; Wort: Array of PChar; Temp: String; begin Temp := 'abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; SetLength(Signs, Length(Temp) + 2); CopyMemory(@Signs[1], @Temp[1], Length(Signs));
Signs[0] := #0; Signs[High(Signs)] := #0;
SetLength(Wort, 1); Wort[0] := @Signs[0];
for X := 0 to 1000 do begin Y := 0; inc(Wort[Y]);
while Wort[Y]^ = #0 do begin Wort[Y] := @Signs[1]; inc(Y);
if Y > Length(Wort) - 1 then begin SetLength(Wort, Y + 1); Wort[Y] := @Signs[1]; end else inc(Wort[Y]); end; end; end; |
In Temp die gewünschten Zeichen eintragen und 400.000.000 Kombinationen pro Sekunde bekommen.
GTA-Place - Fr 18.07.08 15:02
Und nun (vermutlich) zum Abschluss: 4.180.000 Kombinationen pro Sekunde, wenn ich das ganze in einer Stringlist speichere. Mehr werde ich wohl nicht rausholen können.
Einzufügen vor dem end; der X-Schleife:
Delphi-Quelltext
1: 2: 3: 4: 5:
| Temp := ''; for Y := 0 to High(Wort) do Temp := Temp + Wort[Y]^;
SList.Add(Temp); |
Aber eigentlich schon erstaunlich schnell.
Jerk - Fr 18.07.08 15:09
edit Vergesst was ich gesagt hab.
walter_b - Fr 18.07.08 16:12
GTA-Place hat folgendes geschrieben: |
Und nun (vermutlich) zum Abschluss: 4.180.000 Kombinationen pro Sekunde, wenn ich das ganze in einer Stringlist speichere. Mehr werde ich wohl nicht rausholen können.
|
Wow, echt verblüffend, Wie schnell der alles durchgehen kann. Vielen Dank für dein Bemühen und Engagement! :beer:
Falls du dich nochmal selbst übertreffen solltest, darfst du das gerne nochmal posten ;)
Hidden - Fr 18.07.08 16:25
Wobei du das natürlich real nochmal mit einem Faktor multiplizieren musst: der Reaktionszeit des Programms, dessen PW du knacken willst - aber das kannst du dir wahrscheinlich denken.
walter_b - Fr 18.07.08 16:41
Und zudem kommt noch die Verschlüsselung, die Erstellung des Keys und alles, was sehr viel Zeit benötigt. Aber ich arbeite daran, die Optimierung geht vorwärts. Mal schauen, was ich letztenendes für eine Leistung hinbringen kann. 1 Mio Passwörter inklusive Hash-Bildung und alles dauerte 38 Sekunden. Das war vor der Optimierung. Jetzt kämpfe ich gerade ncoh mit diversen Problemen, aber wird bald mal soweit sein. (Und diesmal deutlich schneller ;))
Delete - Fr 18.07.08 17:51
GTA-Place hat folgendes geschrieben: |
Und nun (vermutlich) zum Abschluss: 4.180.000 Kombinationen pro Sekunde, wenn ich das ganze in einer Stringlist speichere. Mehr werde ich wohl nicht rausholen können.
Einzufügen vor dem end; der X-Schleife:
Delphi-Quelltext 1: 2: 3: 4: 5:
| Temp := ''; for Y := 0 to High(Wort) do Temp := Temp + Wort[Y]^;
SList.Add(Temp); |
Aber eigentlich schon erstaunlich schnell. |
@GTA da geht doch noch mehr ;-)
einfach statt 'ner tstringlist 'n array of strings hernehmen und zuvor z.b. mit 5 mio einträgen mal 12 byte länge initialisieren... dann sparste dir die ständige neuallokation und das umschichten des speichers...
GTA-Place - Fr 18.07.08 18:26
Normalerweise braucht man aber ja gar keine Speicherung der Werte. Das erzeugte Wort wird ja eigentlich gleich mit dem Passwort überprüft, daher gings mir da weniger um die Stringlist, als um die Generierung.
Und wenn, dann prüf ich vorher, wie viele Einträge ich brauche: (Anzahl der Zeichen)^Länge :)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!