Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Copy() zu langsam, gibts was schnelleres?


walter_b - Do 17.07.08 12:25
Titel: Copy() zu langsam, gibts was schnelleres?
Hallo Zusammen. Ich bin gerade mein Skript am Optimieren, da es im Moment deutlich zu langsam ist.

Lasse ich den Vorgang 1'000'000 ohne nachfolgende Textstelle durchlaufen, dauert es konstant 16ms. Entkommentiere ich nachfolgende Textstelle, so dauert es bei 1'000'000 Durchgängen ungefähr 400ms.

Es handelt sich um folgenden Teil:


Delphi-Quelltext
1:
2:
3:
bigpass:='helloworld0000';
anf:=Copy(bigpass,0,7);
ende:=Copy(bigpass,8,7);


Um euch noch zu erläutern, was ich genau will: Bigpass wird noch dynamisch, hier wurde es für die Optimierung statisch gemacht. Jedoch behält es eine konstante länge von 14 Zeichen. Nun brauche ich jedoch die ersten sieben Zeichen in einem String und die zweiten sieben ebenfalls nochmal in einem anderen. Wie gesagt, die obengenannte funktion ist deutlich zu langsam. Gibt es ev. etwas, das mir den String genau in der Mitte halbiert? Oder gibt es eine sonstige, schneller Möglichkeit?

Vielen Dank.


Bernhard Geyer - Do 17.07.08 12:29

Stichworte wären FastMM und FastCode Project (http://www.fastcodeproject.org/)


Tilman - Do 17.07.08 12:32

Hab grad kein Delphi zur Hand, allerdings könnte eine Variante nach folgendem Schema denkbar sein:


Delphi-Quelltext
1:
2:
3:
4:
5:
type tMyStr = record
case boolean of
  true: (str: array[1..14] of Char;);
  false: (pre: array[1..7] of Char; post: array[1..7] of Char;);
end;



Ich kanns grad selbst nicht testen, aber damit könnte es möglich sein direkt auf den Speicherbereich der Teilstrings zuzugreifen. Muss aber sagen dass ich mit diesen case-Anweisungen in Typen nicht wirklich auskenne.


Jerk - Do 17.07.08 12:43

Vllt ist ein Grund das dein String 14 Zeichen hat, also Index von 0 bis 13 aber du bis stelle 15 kopieren willst?


nagel - Do 17.07.08 12:46

7 Zeichen ab Stelle 8 geht bis 14 und Strings fangen bei 1 und nicht bei 0 an.


walter_b - Do 17.07.08 12:48

user profile iconBernhard Geyer hat folgendes geschrieben:
Stichworte wären FastMM und FastCode Project (http://www.fastcodeproject.org/)


Mit FastMM wird es auf eta 320 reduziert, allerdings immernoch deutlich zu langsam.

user profile iconJerk hat folgendes geschrieben:

Vllt ist ein Grund das dein String 14 Zeichen hat, also Index von 0 bis 13 aber du bis stelle 15 kopieren willst?


Ich habe das ganze ursprünglich mit Copy(a,0,7) und Copy(a,7,7) gemacht und a war so definiert: "12345671234567". Als Ergebnis erhielt ich 1234567 und 7123456. Deshalb habe ich den zweiten angepasst und so funktionierte es. Von da her denke ich nicht, dass dies der Fehler ist.


user profile iconTilman hat folgendes geschrieben:

Ich kanns grad selbst nicht testen, aber damit könnte es möglich sein direkt auf den Speicherbereich der Teilstrings zuzugreifen. Muss aber sagen dass ich mit diesen case-Anweisungen in Typen nicht wirklich auskenne.


Hm... Danke, werde mir das mal anschauen.


BenBE - Do 17.07.08 12:50

Könntest Du etwas mehr Source posten, weil direkt aus diesem Aufruf kann man nicht viel sagen, wie das am besten zu optimieren ist.

Aber wie ich schon im andren Thread angedeutet hab:
Speicher VOR der Schleife alloziieren und dann mit direkten Speicher-Zugriffen arbeiten. Bitte dabei beachten, dass Anfang und Ende Read-Only genutzt werden müssen (sonst erzeugt Delphi Kopien davon --> Performance Drop).

Konkret kann man da aber erst was bei etwas mehr Code sagen, weil dort sich die exakte Nutzung besser erschliet.


walter_b - Do 17.07.08 13:03

Zur kurzen Erläuterung: Gen() geht alle Kombinationen durch (Buchstabenkombinationen, also A, AA, AB etc.). Anschliessend würde aus der aktuellen Kombination (Wort) ein 14 Zeichen langer String erstellt werden (Sorry BenBE, aber das mit dem Null-Byte habe ich noch nicht anpassen können ;)). Hier habe ich das bigpass jedoch statisch gemacht. Danach sollte das ganze mit parityshift noch ein wenig hässlich gemacht werden und mit DecodeText (wurde hier weggelassen) verschlüsselt und nachher zusammengesetzt. Falls ihr sonst noch irgendwo eine Optimierungsmöglichkeit seht, wäre ich euch sehr dankbar :)


Edith: Wegen der angedeuteten Optimierung von dir, BenBE: Da ich mich nicht so wirklich mit PChar auskenne, weiss ich nicht recht, wie ich das anwenden soll. :oops: :cry:


alzaimar - Do 17.07.08 13:11

Ändert doch aber nichts am der Performancebremse. Das es sich hier um konstante Längen handelt, dürfte man mit einigen Kopier- und Castingoperationen weiter kommen. So gehts ein wenig schneller:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
Var
  bigpass,anf,ende : String;

Type
  P4 = ^Integer;
  P2 = ^Word;
  P1 = ^Byte;

Var
  p : Integer;

begin
  SetLength (anf,7);
  setLength (ende,7);
  p := integer (@bigpass[1]);
  P4(@anf[1])^  := P4(p)^;
  P2(@anf[5])^  := P2(p+4)^;
  P1(@anf[7])^  := P1(p+6)^;
  P4(@ende[1])^ := P4(p+7)^;
  P2(@ende[5])^  := P2(p+12)^;
  P1(@ende[7])^  := P1(p+13)^;
End;


walter_b - Do 17.07.08 13:19

user profile iconalzaimar hat folgendes geschrieben:
Ändert doch aber nichts am der Performancebremse. Das es sich hier um konstante Längen handelt, dürfte man mit einigen Kopier- und Castingoperationen weiter kommen. So gehts ein wenig schneller:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
Var
  bigpass,anf,ende : String;

Type
  P4 = ^Integer;
  P2 = ^Word;
  P1 = ^Byte;

Var
  p : Integer;

begin
  SetLength (anf,7);
  setLength (ende,7);
  p := integer (@bigpass[1]);
  P4(@anf[1])^  := P4(p)^;
  P2(@anf[5])^  := P2(p+4)^;
  P1(@anf[7])^  := P1(p+6)^;
  P4(@ende[1])^ := P4(p+7)^;
  P2(@ende[5])^  := P2(p+12)^;
  P1(@ende[7])^  := P1(p+13)^;
End;


Irgendwie kann ich dem ganzen nicht wirklich folgen. Könntest du mir erklären, was hier genau geschieht? Worauf greift z.b. @anf[1] zu?


alzaimar - Do 17.07.08 13:26

Na anf[1] ist das erste Zeichen des Strings 'anf' und '@' die Adresse davon. P4(@anf[1]) sagt Delphi, das an dieser Stelle ein Integer steht und P4(@anf[1])^ liefert diesen Integer. Geht aber noch schneller:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
Type
  T7 = array[0..7] Of Byte;
  P7 = ^T7;

Var
  p : Integer;
begin
  SetLength (anf,7);
  setLength (ende,7);
  p := integer (@bigpass[1]);
  P7(@anf[1])^  := P7(p)^;
  P7(@ende[1])^ := P7(p+7)^;
End;


walter_b - Do 17.07.08 13:34

Aah, das ist demfall bloss für die Definition von anf und ende, oder? Womit würde ich nachher weiterarbeiten? P7? Oder wird nachher einfach der String normal in anf und ende gespeichert? :gruebel:


alzaimar - Do 17.07.08 13:35

Ausprobieren (die Strings sind natürlich korrekt befüllt).


Allesquarks - Do 17.07.08 13:40

PChar ist einfach wie der Name schon sagt ein Zeiger auf Buchstaben also ziemlich ähnlich zum array of byte. Insbesondere verzichtet es auf vieles von dem Delphi-String Schnickschnack. Je nach deiner Programmierung kann man Strings üblicherweise extrem optimieren. Delphi ruft bsp. bei jeder Benutzung von strings intern die Funktion uniquestring auf, die sicherstellt, dass man nicht andere Variablen (da strings eigentlich auch nur Zeiger sind) ändert. Wenn du darauf achtest dann kannst du dir diesen Overhead durch pchar schoneinmal sparen. Ich schätze auch mal, dass der dumme Compiler wegen deiner 14 #0 auch vierzehnmal die Stringverkettung aufruft. Ich nehme an, du willst damit garantieren, dass der string auch 14 Zeichen lang ist. Doch in diesem Fall wäre der kürzeste Code (deiner) nicht der eleganteste. In deinem Fall würde ich einfach eine Abfrage einbauen, ob der überhaupt so lang ist. Das wäre wesentlich schneller. Falls es wirklich nur darum geht, dass der mindestens 14 Zeichen lang ist würde auch ein simples setlength reichen. Das wäre zumindest noch schneller als die derzeitige Version schätze ich.

Speziell copy kann man bei strings auch komplett vermeiden, indem man sich über einen Zeiger und eine Länge einfach merkt, wo man in einem globalen String arbeiten möchte.

P.S.:mit dem @ bekommt man die Adresse der Variablen, an die man mit ^ (dereferenzieren) dann schreiben kann.


BenBE - Do 17.07.08 13:47

Wenn es hier wirklich darum geht, mit konstanter Länge zu arbeiten, würde ich keine Strings umherschubsen, sondern Array of Char entsprechend dimensionieren und daraus ableiten. String sollte in dem Kontext wirklich nur dort verwendet werden, wo solch ein Puffer als Zeichenfolge dargestellt werden muss; ansonsten mit direktn Speicherzugriffen arbeiten, wie oben gezeigt.

Interessant könnte in dem Zusammenhang auch die Funktion StrPas sein ;-)


walter_b - Do 17.07.08 13:56

@all: Vielen Dank für eure Geduld und Hilfe :) Habe zuvor noch nie mit PChar gearbeteitet, aber werde das ganze jetzt mal bisschen genauer anschauen und mich ins Thema einarbeiten versuchen. Mal schauen, ob es was bringt. ;)


walter_b - Do 17.07.08 14:30

Was genau macht die Integerfunktion hier:


Delphi-Quelltext
1:
p := integer (@bigpass[1]);                    


Habe anf, ende und p auslesen lassen. anf und ende passen wunderbar :) Hingegen für p kommt was seltsames raus. Habe die Funktion nirgends in der Hilfe gefunden.


Und ausserdem verstehe ich nicht wirklich, wofür T7 deklariert wird, da es ja nicht verwendet wird.


Hidden - Do 17.07.08 14:57


Delphi-Quelltext
1:
p := integer (@bigpass[1]);                    

p ist ein Zeiger. Dass der einen komischen Inhalt hat, braucht dich nicht zu wundern, du musst ihn dereferenzieren, so ist es nur eine Adresse.

Integer ist ein TypeCast und keine funktion: Es wird so behandelt, als stände an dieser Position ein Integer. Dieser ist 4 Byte lang und umdfasst somit die ersten vier Zeichen nach bigpass[1].

mfG,


Tilman - Do 17.07.08 15:21

So, habs mal kurz ausprobiert:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type tMyStr = record
case boolean of
  true: (str: array[1..14] of Char;);
  false: (anfang: array[1..7] of Char; ende: array[1..7] of Char;);
end;

var
  a: tMyStr;
[..]
    a.str :='helloworld0000';
    // a.anfang = anfang
    // a.ende = ende


Funzt relativ schnell. Allerdings kann ich dir nicht sagen wie man a.str einen String zuweisen kann; mit Konstanten Literalen klappts zwar, aber irgendwie sollte man ja auch einen string casten können :gruebel:


walter_b - Do 17.07.08 15:29

Habe gerade ein Problem. Die aktuelle Kombination steckt ja in "Wort". Wie bringe ich jetzt den Wert davon in den Array of Char bigpass? Steht: Incompatible types: Array and String.


Hidden - Do 17.07.08 15:38

Einfach typecasten: TBigpass(Wort)

Edit: ich sehe gar keine Variable namens 'Wort'.. außerdem ist bigpass ein String.. Sollte es sich um String und Array handeln und du a b zu weisen willst, musst du b nach a typecasten: a := TA(b) //TA = typ von a..

@oben: müsste es nicht ein packed record sein?


Allesquarks - Do 17.07.08 15:57

Das beste wäre wohl du deklarierst direkt wort als ein pchar oder array of character. Ganz dirty auf deine Weise könntest du auch mychararray=@wort[1]; Aber dann mixt du auf dem gleichen Speicherbereich nen string und nen array und die sehen leider ausserhalb der reinen Buchstabenfolge nicht gleich aus. Solange du nur liest, würde das wahrscheinlich sogar gehen. Ich würde dir aber raten das so nicht zu machen. Kopier lieber einmal initial Buchstabe für Buchstabe in dein array rüber. Nebenbei für pchar bietet delphi glaube ich sogar ein wenig Compilermagic. Könnte also sein, dass wenn du edit1.text:=mypchar machst der das intern so auflöst dass das funktioniert, dann würdest du noch nichtmal die Bequemlichkeit der strings vermissen.


walter_b - Do 17.07.08 16:08

user profile iconHidden hat folgendes geschrieben:
Einfach typecasten: TBigpass(Wort)

Edit: ich sehe gar keine Variable namens 'Wort'.. außerdem ist bigpass ein String.. Sollte es sich um String und Array handeln und du a b zu weisen willst, musst du b nach a typecasten: a := TA(b) //TA = typ von a..




So sieht der Spass im Moment aus. Direkt nach dem End der While-Schlaufe könnte man mit writeln(wort); alle Kombinationen laufend auslesen lassen. Und Wort ist auch oben bei den Variabeln als String definiert. bigpass wurde neu zu einem Array umgeformt. Jetzt würde ich halt gerne den Wert des Strings in den Array packen. Wenn ich bigpass statisch definiere, dann erreiche ich mit der aktuellen Konfiguration für 1 Mio Kombinationen um die 20ms herum. Diese statische Definition verbraucht einen grossen Teil dieser 20ms selbst. Wenn ich das jetzt noch so dynamisch reinschreiben lassen könnte, dann wäre die Zeit bisher wirklich wunderbar!

(Das ganze Programm sollte eine Zeit von ca. 1 Sekunde für 4 Mio Kombinationen erreichen, dann wäre ich glücklich ;)).

Also falls jemand eine möglichst schnelle Lösung für das Reinschreiben hat, dann bitte posten. :)


Edit: Bei TBigpass(Wort); kommT: Undeclared identifier: 'TBigpass'



user profile iconAllesquarks hat folgendes geschrieben:
Nebenbei für pchar bietet delphi glaube ich sogar ein wenig Compilermagic. Könnte also sein, dass wenn du edit1.text:=mypchar machst der das intern so auflöst dass das funktioniert, dann würdest du noch nichtmal die Bequemlichkeit der strings vermissen.

Ich arbeite in einer Consolen-Applikation, also kein edit1 ;) Und wegen der Strings: Es geht mir nicht um die Bequemlichkeit, sondern ich strebe nach Geschwindigkeit :twisted:


Hidden - Do 17.07.08 16:21

Zitat:
Edit: Bei TBigpass(Wort); kommT: Undeclared identifier: 'TBigpass'

:lol:


Gemeint war:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
type
  TBigPass = Array[0..13] of Char;

procedure DoSomething;
var
  BigPass: TBigPass;
  Wort: String;
begin
  BigPass := TBigPass(Wort);
  Wort := String(TBigPass);
end;


Ich wiederhols nochmal: Müsste es nicht ein packed record sein? Sonst wäre nicht sichergestellt, dass die Daten auch direkt hintereinander stehen und beim typecasten könnte ganz schöner Mist passieren..

mfG,


Tilman - Do 17.07.08 16:24

user profile iconHidden hat folgendes geschrieben:

Ich wiederhols nochmal: Müsste es nicht ein packed record sein? Sonst wäre nicht sichergestellt, dass die Daten auch direkt hintereinander stehen und beim typecasten könnte ganz schöner Mist passieren..

mfG,


Kann sein - davon habe ich keine Ahnung. Probiers aus ;)


walter_b - Do 17.07.08 16:25

Ach soooh, sorry :D Habe das jetzt geändert und es erscheint ein Invalid typecast auf der Zeile von BigPass := TBigPass(Wort);


walter_b - Do 17.07.08 16:29


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
Type
  T7 = array[0..7] Of Byte;
  P7 = ^T7;

Var
  p : Integer;
begin
  SetLength (anf,7);
  setLength (ende,7);
  p := integer (@bigpass[1]);
  P7(@anf[1])^  := P7(p)^;
  P7(@ende[1])^ := P7(p+7)^;
End;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type tMyStr = record
case boolean of
  true: (str: array[1..14] of Char;);
  false: (anfang: array[1..7] of Char; ende: array[1..7] of Char;);
end;

var
  a: tMyStr;
[..]
    a.str :='helloworld0000';
    // a.anfang = anfang
    // a.ende = ende


Welchen der beiden soll ich jetzt verwenden? :?!?:


Tilman - Do 17.07.08 16:29

user profile iconwalter_b hat folgendes geschrieben:
Ach soooh, sorry :D Habe das jetzt geändert und es erscheint ein Invalid typecast auf der Zeile von BigPass := TBigPass(Wort);


Ja dasselbe hatte ich vorhin auch schon. Irgendwie mag Delphi scheint's das casten von arrays nicht so gerne.


Hidden - Do 17.07.08 16:32

hmm.. Probier mal, TBigPass(Pointer(Wort))


walter_b - Do 17.07.08 16:35

user profile iconHidden hat folgendes geschrieben:
hmm.. Probier mal, TBigPass(Pointer(Wort))

Invalid typecast


Allesquarks - Do 17.07.08 17:15

Hm ist die Funktion decodeTxt von dir. Weil wenns so ist würde ich die einfach anpassen, dass die auch mit diesen "neuen" Datentypen umgehen können. Wenn dem nicht so ist musst du das wohl oder übel in einen String bringen. Deshalb wird es wahrscheinlich von Erfolg gekrönt sein, wenn du über string() typecastest. Ich vermute aber, dass wegen des anderen Layouts intern das dann unweigerlich zu Laufzeitfehlern führt. Da wäre dann wohl auch pchar geeigneter als ein array (obwohl es das ja fast ist), weil delphi dann mit Compiler-Magic das für dich hinbiegt.


walter_b - Do 17.07.08 17:49

Dies ist die DecodeText-Funktion. Und nein, sie ist nicht von mir, sondern bezieht sich auf eine Verschlüsselung im DEC. Hm... Irgendwie sollte man dies schon hinbringen, die umzuschreiben, denke ich mal.
Oder wäre es doch einfacher, den Array in einen pchar umzuwandeln? Wie sieht es mit der Geschwindigkeit aus?


walter_b - Do 17.07.08 18:04

Ich habe das ganze jetzt gleich mal angepasst, dass auch die #0 am Ende angehängt werden.


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:
procedure Gen();
type
  T7 = array[0..7] Of Byte;
  P7 = ^T7;
  TBigPass = Array[0..13] of Char;

var
  X, Y, prev, val, bp, I, p:  Integer;
  Wort, binlm, ret, part, wortchen:  String;     // Direkt String
  BigPass: TBigPass;
  fChar: PChar;
  Len : Integer;

[...]
        inc(Wort[Y]);
      Wort[Y - 1] := 'A';
    end;
    Len := Length(Wort);
    SetLength(Wortchen, Len+14);
    wortchen:=Wort;
    FillChar(Wortchen[Len+1], 14, #0);

[...]


Wortchen enthält hier die aktuelle Kombination. Jeodch wäre jetzt wieder das selbe Problem mit dem typecasten in den Array.


Edit: das ganze ist zu langsam!


Allesquarks - Do 17.07.08 18:07

Hm möglich das umzuwandeln ist das schon es ist nur die Frage mit welchem Aufwand. Die DecodeText abzuändern bringt insofern wahrscheinlich auch wenig, da ja init(key) dann einen String erwartet und den musst du nunmal liefern.
Hm du übergibst ja zwei strings anf und ende. Kannst du nicht deine Schleifen oben zerfleischen, so dass die da nicht in einem string stehen müssen. Ich meine, dass du in der ganzen Funktion mit den beiden (anf/ende) arbeitest. Meiner Meinung müsste das gehen.
Ich kenn leider den genauen Aufbau von string nicht, deshalb weiß ich auch nicht, was da der Compiler beim casten einsparen kann, würde dir aber dringend empfehlen auf pchar zu gehen anstatt array of char, weil das ist dem string glaube ich näher.


walter_b - Do 17.07.08 18:11

Ich habe nicht genau verstanden, in welcher Schlaufe du meinst. Meinst du nachher den Teil mit bp, val und prev? Dort willst du anf und ende zusammenlassen?

Ich werde mal schauen, was mich mit pchar machen kann.


Edit: Ich habe gerade was gefunden... würde es helfen, wenn die Kombination in Wort gespeichert ist und wort als "array of char" definiert ist? Oder kriege ich nachher einfach das Problem, dass ich die #0 nicht mehr anhängen kann?


Allesquarks - Do 17.07.08 18:29

Ok es gibt mannigfaltige Möglichkeiten! Ich glaube die eleganteste hatten wir aber noch nicht. Das ist ja ganz offensichtlich eine DES entschlüsselung. Ihc nehme mal an die gibts wie Sand am Meer in Open Source.
Wenn ich das richtig sehe baust du dir mit den Schleifen irgendwelche Schlüssel in Hex zurecht? Am schnellsten wäre es die Schlüssel direkt binär zu bauen und sich das init zu sparen, sondern direkt in den Key-Slot des DES Algorithmus zu schreiben.

Und zu deiner Frage:
Und ja wort direkt zu nem array of char zu machen bringt vlt was. Das Problem ist vielmehr das auseinanderrupfen in anf und ende, denn das musst du machen, solange das init den Key als string erwartet (wobei in diesem speziellen Fall vermute ich, dass es nicht einmal etwas bringen würde, wenn init pchars akzeptiert).

Edit: Ok mein Irrtum du erzeugst doch nicht hex sondern klartext passwörter. Frage: wie groß ist die Schlüssellänge und wie werden aus den Passwörtern die Schlüssel berechnet? md5 sha? Und brauchst du nur die binär keys am Ende oder die Passwörter?


walter_b - Do 17.07.08 19:01

Es wird folgende Verschlüsselung angewandt:

mcrypt_ecb(MCRYPT_DES, $a, "KGS!@#$%", MCRYPT_ENCRYPT)


walter_b - Do 17.07.08 19:12

Yes, ich habe das Teil gefitzt ;) Man muss den 14-stelligen String nicht mehr aufteilen. Wenn man ihn ganz durch die normale Funktion laufen lässt, dann bearbeitet er nur den ersten Teil des Strings. Ich habe jetzt noch eine zweite Funktion geschrieben, der nur den zweiten Teil bearbeitet, ohne dass man den String aufteilen muss.


BenBE - Do 17.07.08 21:39

Ein Record kann nicht direkt gecastet werden. Mann muss zuerst auf einen Pointer-Type casten, der auf diesen Record-Typ zeigt und diesen anschließend dereferenzieren ...


Framige - Sa 26.07.08 01:21

Hi walter_b,
könntest du den gesamten Source zur Verfügung stellen?
Ich suche auch so etwas, allerdings in die andere Richtung.
Ich möchte einen String vorgeben und die Funktion soll mir
dafür einen gültigen LM-Hash zurückliefern.
Framige

P.S.
Und nein, ich möchte nicht den Rainbowtables Konkurenz machen,
das ganze ist für eine Hausinterne Untersuchung gedacht...


BenBE - Sa 26.07.08 02:39

Siehe dazu die Wiki: http://de.wikipedia.org/wiki/LM-Hash