PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : code optimierung



Gaara
13.06.2010, 00:14
hi, ich schreib immoment nen MD5 cracker, eig. nicht weil ich ihn brauchen oder sonstwas, geht nur darum dass ich wenigstens irgendwas code...
ich hab schon von vielen gelesen dass ihre md5 cracker mit ca 1,2mio hashs/s cracken und meiner macht ca. 8mio/minute was mir um ehrlich zu sein etwas zu langsam is... ich weis nicht wie die anderen cracker die hashs erstellen aber ich hab eine funktion geschrieben die alle kombinationen aus groß/klein buchstaben,zahlen und sonderzeichen berechnet, diese strings wandel ich dann in hashs um... somit ist es zwar langsam aber dafür hab ich komplett alle möglichkeiten durch.
da diese funktion aber sehr groß und ich vermute auch umständlich ist würd ich gern hier mal fragen wie ihr das lösen würdet...


string ausgabe(int a, int b, int c,int d, int e, int f,int g, int h, int i, int j,int k,int l,int m, valarray<string> &arr)
{
string passwort;
if(i==-1)
{
passwort=arr[m]+arr[l]+arr[k]+arr[j];
return passwort;
}
else if(h==-1)
{
passwort=arr[m]+arr[l]+arr[k]+arr[j]+arr[i];
return passwort;
}
else if(g==-1)
{
passwort=arr[m]+arr[l]+arr[k]+arr[j]+arr[i]+arr[h];
return passwort;
}
else if(f==-1)
{
passwort=arr[m]+arr[l]+arr[k]+arr[j]+arr[i]+arr[h]+arr[g];
return passwort;
}
else if(e==-1)
{
passwort=arr[m]+arr[l]+arr[k]+arr[j]+arr[i]+arr[h]+arr[g]+arr[f];
return passwort;
}
else if(d==-1)
{
passwort=arr[m]+arr[l]+arr[k]+arr[j]+arr[i]+arr[h]+arr[g]+arr[f]+arr[e];
return passwort;
}
else if(c==-1)
{
passwort=arr[m]+arr[l]+arr[k]+arr[j]+arr[i]+arr[h]+arr[g]+arr[f]+arr[e]+arr[d];
return passwort;
}
else if(b==-1)
{
passwort=arr[m]+arr[l]+arr[k]+arr[j]+arr[i]+arr[h]+arr[g]+arr[f]+arr[e]+arr[d]+arr[c];
return passwort;
}
else if(a==-1)
{
passwort=arr[m]+arr[l]+arr[k]+arr[j]+arr[i]+arr[h]+arr[g]+arr[f]+arr[e]+arr[d]+arr[c]+arr[b];
return passwort;
}
else
{
passwort=arr[m]+arr[l]+arr[k]+arr[j]+arr[i]+arr[h]+arr[g]+arr[f]+arr[e]+arr[d]+arr[c]+arr[b]+arr[a];
return passwort;
}das hier ist die funktion

valarray sieht so aus:

valar[0]="a";
valar[1]="b";
valar[2]="c";
valar[3]="d";
valar[4]="e";
valar[5]="f";
valar[6]="g";
valar[7]="h";
valar[8]="i";
valar[9]="j";
valar[10]="k";
valar[11]="l";
valar[12]="m";
valar[13]="n";
valar[14]="o";
valar[15]="p";
valar[16]="q";
valar[17]="r";
valar[18]="s";
valar[19]="t";
valar[20]="u";
valar[21]="v";
valar[22]="w";
valar[23]="x";
valar[24]="y";
valar[25]="z";
valar[26]="1";
valar[27]="2";
valar[28]="3";
valar[29]="4";
valar[30]="5";
valar[31]="6";
valar[32]="7";
valar[33]="8";
valar[34]="9";
valar[35]="0";
valar[36]="!";
valar[37]="<";
valar[38]="§";
valar[39]="$";
valar[40]="%";
valar[41]="&";
valar[42]="/";
valar[43]="(";
valar[44]=")";
valar[45]="=";
valar[46]="?";
valar[47]="`";
valar[48]="´";
valar[49]="@";
valar[50]="+";
valar[51]="*";
valar[52]="~";
valar[53]="'";
valar[54]="#";
valar[55]="-";
valar[56]="_";
valar[57]=".";
valar[58]=":";
valar[59]=",";
valar[60]=";";
valar[61]="{";
valar[62]="[";
valar[63]="]";
valar[64]="}";
valar[66]="A";
valar[67]="B";
valar[68]="C";
valar[69]="D";
valar[70]="E";
valar[71]="F";
valar[72]="G";
valar[73]="H";
valar[74]="I";
valar[75]="J";
valar[76]="K";
valar[77]="L";
valar[78]="M";
valar[79]="N";
valar[80]="O";
valar[81]="P";
valar[82]="Q";
valar[83]="R";
valar[84]="S";
valar[85]="T";
valar[86]="U";
valar[87]="V";
valar[88]="W";
valar[89]="X";
valar[90]="Y";
valar[91]="Z";und so wird die funktion (dummerweise auf gewisse weise) aufgerufen:

int arr_len = valar.size();

for(int a = -1;a < arr_len;a++)
{
for(int b = -1;b < arr_len;b++)
{
for(int c = -1;c < arr_len;c++)
{
for(int d = -1;d < arr_len;d++)
{
for(int e = -1;e < arr_len;e++)
{
for(int f = -1;f < arr_len;f++)
{
for(int g = -1;g < arr_len;g++)
{
for(int h = -1;h < arr_len;h++)
{
for(int i = -1;i < arr_len;i++)
{
for(int j = 0;j < arr_len;j++)
{
for(int k = 0;k < arr_len;k++)
{
for(int l = 0;l < arr_len;l++)
{
for(int m = 0;m < arr_len;m++)
{

ausgabe(a,b,c,d,e,f,g,h,i,j,k,l,m,valar);

}

}
}
}
}
}
}
}
}
}
}
}
}
}das ganze funktioniert echt gut und die trefferquote ist ja auch nicht schlecht, aber ich vermute dass sich das ganze extrem optimieren lässt, ich möchte hier eig. nicht unbedingt code oder sonst was, (falls ihr welchen habt ist er natürlich dennoch erwünscht) sondern reine logische denkanstöße würden mir eig. schon reichen.

ocz
13.06.2010, 00:28
Bitte mehr so Threads, endlich mal was interessantes :)
Mal ne Frage: Ist das java code oder warum rufst du da ne size funktion auf nem Array auf (in dem Falle wäre die Langsamkeit ja erklärt)?
Ansonsten vielleicht erstma gucken was der Compiler da hinterher draus macht und auf speed optimieren lassen :)

Edit: der übersichtlichkeit halber kannst du die ganzen geschweiften Klammern bei den Forschleifen weglassen

deagleD
13.06.2010, 00:29
Die besten Hashcracker arbeiten, soweit ich weiss, mit dem GPU und nicht mit dem CPU, da dieser um einiges schneller ist.

Nur als kleiner Hinweis... zu deinem Code kann ich leider nicht viel sagen :D

Grüße

Gaara
13.06.2010, 00:42
also es handelt sich um c++^^ wieso ich ne size funktion aufrufe ist einfach zu erkläre, es handelt sich dabei um keinen normalen array sondern um nen valarray, dieser liefert solche und paar weitere funktionen.
den rest deiner aussage kann ich irgendwie nicht ganz auffassen, was der compiler hinterher draus macht?^^ und was meinst du optimieren lassen? das kann ja eig. nur ich machen oder?

als IDE benutze ich übrigends code::blocks

werd jetzt pennen gehen, also antworten sind vor 9 uhr nicht mehr zu erwarten^^ auf antworten freu ich mich natürlich.

p.s., der verständlichkeit halber:

die funktion hat schrittweise folgende ausgabe:


aaaa
baaa
caaa
.....
zaaa
abaa
bbaa
....
usw.

fred777
13.06.2010, 00:46
Wenn du wüsstest was der Compiler noch aus deinem Code fertigt.
Wie der Name Hochsprache schon sagt, wird dein Code erst nochmal tüchtig verändert, dann in Instruktionen übersetzt. Als Beweis kann man die smarten ASM Apps vorzeigen ;)

Gaara
13.06.2010, 09:40
dass mein code verändert wird und viele compiler den code automatisch bisschen optimieren is mir bewusst, aber bei meinem problem hilft mir das nicht unbedingt weiter, da ich echt ka hab was ich noch tun soll... ich werd mir jetzt erstmal nen analyser holen und schaun wo die meiste zeit drauf geht... für weitere vorschläge bin ich dankbar.

psyborg
13.06.2010, 09:47
Du kannst ja die kritischen Zeilen in Assembler coden, so sparst du Zeit.

Sonst sieht der Code schon recht optimiert aus.. (bin da eh nicht so der experte)

The-God-of-all
13.06.2010, 09:58
Mir fällt jetzt eigentlich nur eines auf, und zwar, dass du mit Strings arbeitest. Du fügst sie immer mit + zusammen. Ich vermute mal, dass der String immer wenn du + aufrufst den kompletten String Inhalt einmal in ein neues Array kopiert weil man ja nicht einfach mal so ein Array verlängern kann. Vielleicht könntest du hier weiter optimieren indem du ein char Array mit fester Länge benutzt und das füllst. Auch sollte man mal überprüfen wie die Performance von dem valarray ist, es kann sein, dass bei einem normalen char Array (was es vermutlich genauso tun würde) die Zugriffszeiten geringer sind. Vor allem weil dann nicht mehr mit String Objekten gearbeitet würde sondern nur noch mit chars.

Du sagtest, dass das ein MD5 Cracker werden soll. Bei einem MD5 Cracker ist normalerweise die Methode für die MD5 Berechnung das kritischste, also das was am Zeit intensivsten ist. Das was du da geschrieben hast ist ja nur die Funktion um die Kombinationen durchzugehen, mehr machst du ja eigentlich gar nicht. Du musst also damit rechnen, dass wenn du die MD5 Funktion implementierst die Geschwindigkeit noch mal um einiges runtergeht (falls du sie noch nicht drinnen hast, ansonsten poste sie am besten mal).

Gaara
13.06.2010, 10:10
also meine oben genannte geschwindigkeit beeinhaltet das Hashing bereits, also noch langsamer würde es nicht werden, über char hab ich auch schon nachgedacht aber auch wenn sich das etwas dumm anhört... ich hab ka wie man nen char an nen char anhängt >.< weil char[0] =+ char[1] funzt in dem fall ja nicht. werd mal googlen, und wenn es jemand weis kann er es mir ja sagen.

//EDIT

kk habs, werds mit strcat machen.

The-God-of-all
13.06.2010, 11:03
Ein char ist immer ein buchstabe. Also kannst du an einen char keinen weiteren char anhängen. Wenn du einen String mit chars bilden willst dann musst du ein char Array nehmen. Die Funktion gibt also ein char[] zurück. Am Anfang am besten eine Variable char[16] passwort; deklarieren. Dann füllst du jeweils die zeichen mit passwort[0] = ...; passwort [1] = ...; so weiter. Wenn du alle Buchstaben drinnen hast musst du noch ein Null Byte anhängen um zu sagen, dass der String da zu ende ist (passwort[lastIndex + 1] = 0;).

Und wie ich oben bereits schrieb ist denke ich auch die Funktion um den Hash zu berechnen noch sehr wichtig. Die solltest du auch nochmal hier posten oder hast du da schon eine fertig optimierte Funktion aus dem Internet verwendet? Weil du musst bedenken, diese Funktion muss für jedes Passwort aufgerufen werden --> Sie wird extrem oft ausgeführt. Da können bereits wenige Optimierungen viel ändern.

Gaara
13.06.2010, 11:39
also für die hashs nehm ich die hashlib++, dass diese viel zeit braucht is mir eig. bewusst aber ich glaub nicht dass ich daran viel drehen kann da meine kenntniss dafür 1. nicht ausreichen und die 2. schon ziemlich ausgereift is.

ein anderes problem das ich gerade hab is dieses:


char passwort[14]; //13 stelliged passwort+\0
char valar[93];
valar[0]="a";
valar[1]="b";
valar[2]="c";
valar[3]="d";
......
valar[88]="W";
valar[89]="X";
valar[90]="Y";
valar[91]="Z";
valar[92]="\0";
strcat(passwort,valar[m]);


hier spuckt mir der compiler ne fehler meldung aus weil valar vom typ const char* sein muss und ich hab um ehrlich zu sein ka wie ich das hinbekomm =/

The-God-of-all
13.06.2010, 11:56
Warum benutzt du dafür die Funktion strcat? Das ist ein unnötiger Aufruf und damit unnötige Performance einbusse. Weiterhin erwartet die Funktion strcat ein char Array was auch Null Terminiert sein muss. Die Funktion strcat ist also nicht dafür geeignet einen einzlnen char an ein char Array anzuhängen. Ich würde einfach immer mitzählen der wie viele Buchstabe es ist und dann direkt passwort[x] = valar[m]; machen. Am Ende dann passwort[x] = 0; und gut ist. x könnte natürlich gut eine int Variable sein die mit 0 initialisiert wird und jedes mal mit x++; erhöht wird wenn ein Buchstabe hinzugefügt wird. Also ungefähr so:

int x = 0;
passwort[x++] = valar[m];
passwort[x++] = valar[n];
passwort[x] = 0;

Gaara
13.06.2010, 12:03
lol stimmt X_x ich seh den wald vor lauter bäumen nicht^^ danke schonmal für deine hilfe^^

Interceptor
13.06.2010, 12:12
Was mir spontan einfällt wäre dies:

Sollte das Programm das erste mal gestartet werden, so legt es eine .txt an in der die ganzen berechneten Hashes liegen(so: Hash:PW).
Wenn du es nun ein zweites mal aufrufst brauchst du sie nicht mehr berechnen sondern suchst einfach die Datei nach dem passenden Hash durch.

Ob dies schneller ist weiß ich nicht, denke aber schon.

MfG Interceptor

The-God-of-all
13.06.2010, 12:18
Sollte das Programm das erste mal gestartet werden, so legt es eine .txt an in der die ganzen berechneten Hashes liegen(so: Hash:PW).

Also wenn man das schon so machen will dann sollte man schon Rainbow Tables nehmen, wenn man nämlich bedenkt, dass er mit 96 Zeichen bis 13 Buchstaben machen will dann kommt man auf 96^13 Passwörter (Galube mir so viel kriegst du nicht auf die Festplatte). Abgesehen davon, dass die Datei zu groß wird (Wenn ich das richtig sehe mehr als 1 TB) dauert das schreiben auf die Festplatte sehr lange, damit kommt man dann sicher nicht mehr auf 8 Mio Hashs/s. Beim nächsten mal muss die Datei dann eingelesen werden. Wenn die Datei nicht nach Hash sortiert ist (was der Fall sein wird) dann geht keine Binäre Suche sprich es müsste in einer TB großen Datei nach einem Wert gesucht werden. Das dauert länger als der Bruteforce so würde ich mal so behaupten.

Gaara
13.06.2010, 12:26
richtig... das wären ca. 33*10^24 passwörter X_x, die suche würde in dem fall sorgar in sql ewig dauern, ne txtdatei zu durchsuchen wäre unter umständen sorgar unmöglich... ich hab das jetzt alles auf char umgestellt, aber für meine 7,2mio berechnungen brauch ich immernoch 1:02 minuten >.< weis echt nicht was ich noch tun kann^^ das einzige was mir jetzt noch einfällt ist dass das hashen zu lange dauert wobei ich mich dann frage wie das die anderen cracker machen...

Interceptor
13.06.2010, 12:32
Stimmt das habe ich nicht bedacht, habe nicht gelesen dass er bis zu 13 Stellen haben will..

MfG Interceptor

Bonkers
13.06.2010, 12:39
Also vielleicht ich stehe gerade massiv auf dem Schlauch, aber warum zum Teufel löst du das mit den ganzen For-Schleifen? Warum nicht einfach rekursiv?



void btf(int size, int pos, char curr[]) {
char* charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
int i;
if(pos < size){
for(i=0; i<strlen(charset);i++){
char test[strlen(curr) + 2];
strcpy(test, curr);
int len = strlen(test);
test[len] = charset[i];
test[len+1] = '\0';
btf(size, pos+1, test);
}} else {
if(match(crackme, curr) == 1) {
printf("Your Hash has been Cracked. md5( %s ) == %s\n", curr, crackme);
exit(0);
}
}
}


Ist vielleicht auch nicht perfekt, aber berechnet auch alle Kombinationen aus dem gegebenen Charset.
(Siehe http://free-hack.com/ansi-c-c-c/56238-%5Bc%5D-md5-cracker.html )

Ich hoffe mal ich hab auch alles richtig verstanden, und hab jetzt nicht aus versehen Mist gepostet :D

Gaara
13.06.2010, 12:48
boah danke^^ genau danach hab ich gesucht... im ersten post sagte ich ja bereits dass mir meine funktion nicht gefällt weil 1. der aufruf scheiße ist und die 1000 if-bedingungen auch... wieso ich es nicht so gelöst hab is einfach... ich weis was rekursive funktionen sind und wie sie funzen, aber wie ich damit ein eigenes problem löse, das is mir atm noch etwas zuviel >.<
jetzt werd ich mir das ganze mal anschaun, weil ich um ehrlich zu sein noch nicht alles versteh was in dieser funktion steht, und auf C&P steh ich nicht^^

The-God-of-all
13.06.2010, 12:56
Also Bonkers ich muss dir natürlich recht geben, dass die Art mit den vielen For Schleifen nicht so besonders schön ist (nicht flexibel, man kann nicht so ohne weiteres die Länge auswählen etc.). Aber der Code wie du ihn gepostet hast hat einige Nachteile was die Performance betrifft.
1. Das charset wird innerhalb der Funktion die Rekursiv aufgerufen wird deklariert. Das bedeutet, dass bei jedem Aufruf ein neues char Array mit dem Charset als Inhalt erzeugt wird. Das ist nicht sonderlich performant. Das sollte eher als Parameter übergeben werden von der FUnktion die die Rekursive Funktion aufruft.
2. Du rufst immer wieder die Funktion strlen auf. Einmal aufrufen und ab da dann immer übergeben und als feste Variable verwenden wäre wesentlich schneller.
3. Du kopierst den String immer wieder. Auch das führt zu einem erheblichen Performance Verlust. Das ist bei Gaaras Source Code nicht der Fall. In der Hinsicht hin ist sein Source Code wesentlich perdormanter als deiner.

Bonkers
13.06.2010, 12:56
void btf(int size, int pos, char curr[]) { // size = Aktuelle Länge; pos = Aktuelle Position; curr = Das aktuelle Passwort
char* charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; // Das Charset halt :D
int i;
if(pos < size){ // Wenn wir noch nicht beim letzen Buchstaben sind...
for(i=0; i<strlen(charset);i++){ // Gehe das ganze Charset durch...
char test[strlen(curr) + 2]; //Hänge die Buchstaben hinten an...
strcpy(test, curr);
int len = strlen(test);
test[len] = charset[i];
test[len+1] = '\0';
btf(size, pos+1, test); // Wir sind ja nicht beim letzten Buchstaben, also rufen wir uns selbst auf. Wenn der letzte Buchstabe erreicht ist, dann gehen wir wegen der For oben im Charset eins weiter. Das macht natürliche jede Instanz von BTF, und somit kommst du auf alle Möglichkeiten.
}} else { // wir haben ein Passwort generiert!
if(match(crackme, curr) == 1) { // Passt der Hash?
printf("Your Hash has been Cracked. md5( %s ) == %s\n", curr, crackme); // Ausgabe, wir haben was gecracked!
exit(0);
}
}
}


:D


In der Hinsicht hin ist sein Source Code wesentlich perdormanter als deiner.

Mir geht es auch absolut nicht um Geschwindigkeit, sondern eher um die Rekursiven Funktionen. Wenn ich was cracken will dann löse ich das über einen GPU-Cracker...

Gaara
13.06.2010, 13:32
was ist aber wenn ich das ganze angeh wie bei meiner funktion, d.h. alle nachteile ausbügle aber das ganze rekursiv löse? bin ich dann nur flexibler oder auch schneller?

//edit

wow, danke bonkers für die kommentierung, das hilft mir sehr :)

EBFE
13.06.2010, 19:26
1. keine Kopierereien und "höhere" Datentypen wie Strings (ein "string[x]" Zugriff artet nämlich intern in einige Calls aus und ist keineswegs mit dem "char* hallo[x]" gleichzusetzen). Gleiches gilt für "Concatenierungen" oder gar "+" Operatoren bei Strings.
nimm ein chararray, initialisiere es am Anfag mit 0 und schreibe direkt die Zeichen rein.

2. alle Infos möglichst im voraus berechnen - so auch die Passwortlänge.
3. MD5 Routine aus den Libs ist keineswegs optimal - denn diese sind dazu gedacht, "echte" Daten zu hashen. Sofern man aber auf 12-13 Zeichen beschränkt ist, kann man einiges wegoptimieren:
das ist nämlich der Algo:
Message-Digest Algorithm 5 – Wikipedia (http://de.wikipedia.org/wiki/Message-Digest_Algorithm_5)
z.B dieser Schritt:
b := ((a + f + k(i) + w(g)) leftrotate r(i)) + b also das einbeziehen der Eingabe (=w(g) Wert):

so schaut der Speicherzugriff bei 20 Zeichen und 64 Runden:


54 ?- show_mem(20, 64).

0000: 0 1 2 3
0004: 4 5 6 7
0008: 8 9 10 11
0012: 12 13 len 15
0016: 1 6 11 0
0020: 5 10 15 4
0024: 9 len 3 8
0028: 13 2 7 12
0032: 5 8 11 len
0036: 1 4 7 10
0040: 13 0 3 6
0044: 9 12 15 2
0048: 0 7 len 5
0052: 12 3 10 1
0056: 8 15 6 13
0060: 4 11 2 9
Zahlen links: aktuelle Runde im Hashalgo, Zahl in der Zeile = Zugriff auf Adresse x in der jeweiligen Runde, LEN ist dabei "Extrabezeichner" für den Zugriff auf den Speicher mit der Längenangabe.

und so bei 4 Zeichen:


53 ?- show_mem(4, 64).

0000: 0 1 2 3
0004: 4 [] [] []
0008: [] [] [] []
0012: [] [] len []
0016: 1 [] [] 0
0020: [] [] [] 4
0024: [] len 3 []
0028: [] 2 [] []
0032: [] [] [] len
0036: 1 4 [] []
0040: [] 0 3 []
0044: [] [] [] 2
0048: 0 [] len []
0052: [] 3 [] 1
0056: [] [] [] []
0060: 4 [] 2 []Zahlen links: aktuelle Rundennummer, Zahlen in der Zeile: Zugriff auf Adresse x in der jeweiligen Runde. [] bedeutet dass hier Zugriff auf 0-initialisierten Speicher stattfand, d.h dass man diesen auch ignorieren kann, da ja eine 0 hinzuaddiert werden sollte)

hier kann man sich also jede Menge Speicherzugriffe sparen.
Zudem lassen sich die letzen 15-18 der 64 Runden (länger her) zurückrechnen, was wiederum eine "Verschnellerung" um 25% bietet. Den ultimativen Boost bringt aber Parallelisierung mittels MMX oder gleich SSE:
Software optimization resources. C++ and assembly. Windows, Linux, BSD, Mac OS X (http://www.agner.org/optimize/)
(hier solltest du, je nach Kenntnissstand, ruhig einige Wochen zum durcharbeiten einplanen ;) )
Damit erreicht man mehere zig Mio Hashs pro Sekunde (z.B auf meinem 3 Jahre altem Laptop 32 Mio Hashs/s pro Kern - gegenüber BarsWFs 27 Mio H/s ;) ). Setzt aber voraus, dass man sich mit SSE erstmal beschäftigt (C++ Compiler wird hier einem keineswegs die Arbeit abnehmen - vielleicht nur insofern, dass er die SSE Register selbstständig vergibt, allerdings muss man dem Compiler an vielen Schritten zu seinem "Glück" verhelfen. Letzendlich schaut der hochoptimierte Code wie Macro-Asm aus:
Distracted: New and faster EmDebr finally done (http://blog.distracted.nl/2009/07/new-and-faster-emdebr-finally-done.html)
(Md5 cracker mit Source, unwesentlich langsamer als BarsWF)

4. Nicht zuletzt solltest du dich mit Profilersoftware vertraut machen, um die tatsächlichen Problemstellen zu finden. Zumindest eine gute Timerbibliothek suchen und einbauen, so dass man die Zeit für einzelne Abschnitte messen kann und so abschätzen, was am meisten Rechenzeit kostet und optimiert werden muss.

Gaara
13.06.2010, 22:46
wow, danke für diesen post.. is ja mal hammer.
da werd ich mich mal durcharbeiten, auch wenns viel arbeit wird^^ aber ich hab gemerkt dass plumpes lesen und sich seine gedanken machen nicht sonderlich viel hilft... deswegen stürz ich mich ins coden :x so lernt man am besten^^ den unteren abschnitt werd ich da natürlich erstmal etwas hinten anstellen da sich das sehr komplex anhört, erstmal will ich die basics perfekt drauf haben.

aber nochmal zurück zu den letzten posts... ich hab das jetzt auf rekursiv und char umgestellt (auch wenn nochnicht perfekt, hatte einfach kein kopf mehr) aber im vergleich zu meiner funktion hab ich nen enormen performance verlusst... manche einfache hashs kamen nichtmal zu nem ergebnis weils mir einfach zu lang dauerte wo meine funktion knapp ne minute gebraucht hat. deswegen frag ich mich... hat meine funktion nen fehler oder ist die rekursive methode vllt. doch nicht so effektiv?

und meine 2. frage is... enden rekursive funktionen die zu lang laufen (wie z.b. wenn ich damit alle 20 stelligen hashs berechne) nicht in nem stackoverflow? schließlich landet doch jeder wieder aufruf oben aufm stack und der erste aufruf bleibt ganz unten liegen. versteh ich da was falsch oder is das tatsächlich ein nachteil?

0x30
13.06.2010, 23:24
Rekursiv ist afaik sehr langsam.

ocz
13.06.2010, 23:28
Rekursiv ist afaik sehr langsam.
Würde Sinn ergeben, vor Allem aufgrund der vielen calls, pushs und pops