Es ist soweit. Hier kommt die komplett überarbeitete neue Version...
28.04.2008: Version 0.5a "Pandora" released
Diese neue Version hat absolut nichts mehr mit der Version 0.3b gemeinsam - sprich alle Beiträge in diesem thread vor diesem sind hiermit hinfällig
Ich habe die Klasse von Grund auf neu programmiert!
Download:
im Anhang [6,39 KB]
Über TBruteForce
Die aktuelle Version verbraucht an sich kaum Arbeitsspeicher (es sei denn der Programmierer entscheidet sich dazu, die erzeugten Kombinationen in irgendeiner Form zwischenzuspeichern). Das bedeutet, dass für die Performance des Vorgangs (abgesehen von der Effektivität des Codes) allein die Prozessorgeschwindigkeit verantwortlich ist.
Bei einem 2GHz Prozessor(kern) liegt die blose Geschwindigkeit bei etwa 50.000.000 Kombinationen pro Sekunde, durch das Zusammensetzen der strings zur Ausgabe verringert sich die Geschwindigkeit auf etwa 2.000.000 Kombinationen pro Sekunde (hier besteht eindeutig Optimierungsbedarf
). Lässt man sich jetzt noch alle Kombinationen sichtbar ausgeben, beispielsweise in einer Konsole, so verringert sich die Geschwindigkeit weiter auf ca. 20.000 Kombinationen pro Sekunde.
So, ich hoffe nun hast Du eine ungefähre Vorstellung in welchen Geschwindigkeitsbereichen man sich mit der Klasse theoretisch und in der Praxis bewegen kann.
Verwendung
Um die Klasse in Betrieb zu nehmen, ist nichts weiter nötig, als die
Unit BruteForce.pas in das Projektverzeichnis zu kopieren und in die uses der fraglichen
Unit aufzunehmen.
Um mit einem einfachen Beispiel zu beginnen: Wir wollen Kombinationen mit 5 Zeichen Länge erzeugen, der Zeichenvorrat soll dabei das Alphabet in Kleinbuchstaben sein. Oder anders ausgedrückt wir wollen alle Kombinationen von aaaaa, aaaab, aaaac, ... bis zzzzx, zzzzy, zzzzz bilden.
Delphi-Quellcode:
var
BruteForce: TBruteForce;
begin
// Instanzierung
BruteForce := TBruteForce.Create;
// Wir wollen 5 Stellen kombinieren, sg. "Nodes"
BruteForce.NodeCount := 5;
// Zeichenvorrat setzen, AlphaLowerCase ist eine Konstante die von der Unit bereitgestellt wird
// Als ElementList erwartet die Klasse ein array of string. BFConstToDynArray wandelt ein
// statisches array of string in ein dynamisches array of string um.
BruteForce.ElementList := BFConstToDynArray(AlphaLowerCase);
// Soderle. Bereits jetzt enthält BruteForce.Value die erste Kombinationen, in diesem Fall aaaaa.
// Also müssen wir die gleich ausgeben.
DoSomething(BruteForce.Value);
// Jetzt gehts ans eigentliche BruteForcen, wir bilden die Kombinationen
// BruteForce.NextValue bildet die nächste Kombinationen und gibt das Ergebnis als string zurück
while not BruteForce.Finished
do begin
DoSomething(BruteForce.NextValue);
end;
// Wuppdi - jetzt sind wir schon fertig ;)
Wie viele Kombinationen die Klasse erzeugen wird lässt sich über
BruteForce.ToDo
auslesen.
Jetzt ist es aber so, dass man jedem Node seinen eigenen Zeichenvorrat zuweisen kann. D.h. wir könnten beispielsweise auch Kombinationen der länge 5 erzeugen, bei denen die letzten beiden Zeichen Ziffern sind. Das ginge so:
Delphi-Quellcode:
var
BruteForce: TBruteForce;
begin
BruteForce := TBruteForce.Create;
BruteForce.NodeCount := 5;
BruteForce.ElementList := BFConstToDynArray(AlphaLowerCase);
// Jetzt kommts ;)
BruteForce.Nodes[0].ElementList := BFConstToDynArray(Numeric);
BruteForce.Nodes[1].ElementList := BFConstToDynArray(Numeric);
DoSomething(BruteForce.Value);
while not BruteForce.Finished do begin
DoSomething(BruteForce.NextValue);
end;
Dieser Code würde alle Kombinationen von aaa00, aaa01,... bis zzz99 ausgeben. Jetzt wunderst Du dich vielleicht, wieso wir den Zeichenvorrat der Nodes 0 und 1 ändern und nicht den der Nodes 3 und 4 (die Zahlen sollen ja rechts hin). Nunja, je weiter ein Node links steht, desto höherwertiger ist er. Deshalb wird der Node, der in der Ausgabe die "rechteste" Stelle repräsentiert über den Index 0 angesprochen. Puh, ich hoffe das ist einigermasen verständlich
Code:
Wort a a a 0 0
Node 4 3 2 1 0
To Do
Bei der Version 0.5a handelt es sich um ein experimentelles Release. Es sind noch kaum Fehlerbehandlungsroutinen eingebaut! Bis jetzt ist es auch so, dass NodeCount
unbedingt vor ElementList gesetzt werden muss (ein Henne-Ei-Problem für das ich bis jetzt keine überzeugende Lösung gefunden habe).
Einbauen will ich noch eine Speichern/Laden Funktion, die Möglichkeit, den BruteForce-Vorgang in beliebig viele Pakete aufzuteilen (Multithreading, Parallel Computing), sowie eine Ausgabe der Kombinationen wahlweise als array of string (bzw. TBFElementList). Ich habe auch schon mit dem Gedanken gespielt, beliebige Dinge kombinierbar zu machen (beispielsweise Integer, Objekte, etc). Aber ich bin mir nicht sicher, ob sich der Aufwand lohnen würde.
Ich würde mich freuen, wenn von euch noch Vorschläge und Anregungen kämen, wie man die Komponente noch erweitern könnte
Download der Klasse im ersten Post im Anhang
Eine Demo mit der neuen Klasse gibt es in kürze.
Leo S.