Entwickler-Ecke
Algorithmen, Optimierung und Assembler - delphi - zufallsgenerator
sataan1337 - Fr 25.01.08 12:37
Titel: delphi - zufallsgenerator
moinsen - bin neu hier ich hoffe mal ich hab die richtige Ecke gefunden für meine frage ^^ - geht um den zufallsgenerator in delphi
also ich hab gelesen dass des ein "linear congruential generator" is nach der formel "x[n+1] = (a + x[n] + c ) mod m" - m wäre ja der Wert den man im quellcode eingibt - jetz meine frage ^^ - wo nimmt delphi die restlichen werte her? (hab nur gelesen dasses allgemeine / zufällige Werte aus dem System wären also systemzeit prozessorauslastung etc - würde aber gern wissen welche das in delphi genau sind und hab nix zu gefunden)
schonmal danke im voraus falls mir jemand helfen kann ^^
mfG. Sataan
btw - ich weiss meine Rechtschreibung is das letzte hoffe mal ihr stört euch daran net allzusehr ^^
BenBE - Sa 26.01.08 12:26
Ein Randomize ruft u.a. die Systemzeit ab. der andere Wert ist eine Konstante.
Genaues müsste ich im Source nachgucken.
sataan1337 - Mo 28.01.08 15:46
wo kann man des nachlesen welche werte bzw konstanten delphi da genau nutzt?
Mitmischer 1703 - Mo 28.01.08 17:26
Warum ist das denn von Belang? :? Es soll doch eh' eine Zufallszahl sein!? :D :wink:
Timosch - Mo 28.01.08 17:49
Mitmischer 1703 hat folgendes geschrieben: |
Warum ist das denn von Belang? :? Es soll doch eh' eine Zufallszahl sein!? :D :wink: |
Weil es nie eine ist.
Computer sind digitale Maschinen und können per definitionem keine zufälligen Aktionen durchführen. Worum es hier geht, sind
Pseudozufallszahlen. Die Frage ist aber: Wie zufällig sind diese wirklich? Das ist vor allem für Kryptografie nötig. Der Delphi-Generator ist für kryptografiesichere Zufallszahlen nicht sicher. Dafür gibt es einen Windows-Generator, dessen Sicherheit in der letzten Zeit stark bezweifelt wird.
Es ist also durchaus sinnvoll, sich mal anzuschauen, was beim Aufruf von random() eigentlich geschieht.
elundril - Mo 28.01.08 18:37
gute Kryptographiprogramme nehmen was anderes. Z.B.: Irgendwie mit Mauskoordinaten o.ä. So machts jedenfalls ein programm von dem mir der Name gerade nicht einfällt.
lg elundril
Timosch - Mo 28.01.08 18:55
elundril hat folgendes geschrieben: |
gute Kryptographiprogramme nehmen was anderes. Z.B.: Irgendwie mit Mauskoordinaten o.ä. So machts jedenfalls ein programm von dem mir der Name gerade nicht einfällt.
lg elundril |
Wenn ich mich richtig erinnere, fordert GnuPG einen beim Erstellen eines Schlüssels auf, die Maus wild herumzubewegen etc. Zumindest gpg4win.
BenBE - Di 29.01.08 02:29
Das mit der Maus kenn ich sowohl von PuTTY (dem Keygen dort), GnuPG, TrueCrypt, und allen anderen GUTEN Krypto-Systemen (die brauchbar sind). Dazu gehört Windows nicht ... Die haben da eher Schnüffel-PRNGs drin.
Außerdem hat das mit dem Maus bewegen nichts mit dem Erzeugen von Zufallszahlen zu tun, sondern eines der Mittel, um den Initialisierungswert des Zufallsgenerator zu verschleiern.
alzaimar - Di 29.01.08 08:26
sataan1337 hat folgendes geschrieben: |
wo kann man des nachlesen welche werte bzw konstanten delphi da genau nutzt? |
Im Quelltext von System.pas
Timosch - Di 29.01.08 15:01
alzaimar hat folgendes geschrieben: |
sataan1337 hat folgendes geschrieben: | wo kann man des nachlesen welche werte bzw konstanten delphi da genau nutzt? |
Im Quelltext von System.pas |
Ist das nicht Compiler-Magic?
sataan1337 - Di 29.01.08 17:00
super ^^ - hilft mir erstmal weiter (mit der system.pas)
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:
| procedure Randomize; var systemTime : record wYear : Word; wMonth : Word; wDayOfWeek : Word; wDay : Word; wHour : Word; wMinute : Word; wSecond : Word; wMilliSeconds: Word; reserved : array [0..7] of char; end; asm LEA EAX,systemTime PUSH EAX CALL GetSystemTime MOVZX EAX,systemTime.wHour IMUL EAX,60 ADD AX,systemTime.wMinute IMUL EAX,60 XOR EDX,EDX MOV DX,systemTime.wSecond ADD EAX,EDX IMUL EAX,1000 MOV DX,systemTime.wMilliSeconds ADD EAX,EDX MOV RandSeed,EAX end; |
des müsste der teil sein (hoffe man darf des hier posten wenn net sagt bescheid ^^)
muss ich mir nurnoch übersetzen was der da genau macht ^^ - is ja sone art assembler code oder? - hat wer infos dazu wie man den "entschlüsseln" kann? - hab mich mit assembler nur innen grundlagen befasst (8085 ftw ^^)
Moderiert von
jasocul: Delphi-Tags hinzugefügt
sataan1337 - Di 29.01.08 17:04
bzw ich find nur listen zum 80xx und ka nach was ich da jetz suchen muss ^^
und btw ^^ zum thema wiso des von interesse is *g - ich finds interessant ^^ - bzw wollt halt mal wissen wie die kiste auf ne zahl kommt (zu gut deutsch ich langweil mich zu tode ^^)
jaenicke - Di 29.01.08 17:06
Was da passiert ist relativ simpel:
Quelltext
1: 2:
| ADD EAX,EDX { sum = sum * 1000 + milliseconds } MOV RandSeed,EAX |
In der ersten Zeile wird in das erweiterte Akkumulatorregister sum * 1000 + millisecond getan und in der zweiten Zeile dieser Wert RandSeed (dem Initialwert des Zufallsgenerators) zugewisen.
sataan1337 hat folgendes geschrieben: |
(zu gut deutsch ich langweil mich zu tode ^^) |
Merkt man an deinem mehrfachen Editieren bzw. Posten xD ;-).
sataan1337 - Di 29.01.08 19:19
also nochmal für die ganz dummen (also mich ^^)
1. asm
2. LEA EAX,systemTime
3. PUSH EAX
4. CALL GetSystemTime
5. MOVZX EAX,systemTime.wHour
6. IMUL EAX,60
7. ADD AX,systemTime.wMinute { sum = hours * 60 + minutes }
8. IMUL EAX,60
9. XOR EDX,EDX
10 MOV DX,systemTime.wSecond
11 ADD EAX,EDX { sum = sum * 60 + seconds }
12 IMUL EAX,1000
13 MOV DX,systemTime.wMilliSeconds
14 ADD EAX,EDX { sum = sum * 1000 + milliseconds }
15 MOV RandSeed,EAX
1. zu asm find ich nix was der befehl macht ^^
2. eax war des doppelregister oder? bzw systemtime welchen wert läd er da rein?
3. speichert den wert im stack (is mehr ne frage als ne aussage will nur wissen ob ich des richtig auffasse)
4. des getsystemtime is in der system.pas net aufgeführt - aber ich schätz mal der liest sich da die einzelnen variablen ein (second etc)
5. überschreibt EAX mit systemTime.wHour
6. multipliziert den wert mit 60 ?
7. addiert systemTime.wMinute zu AX
8. multipliziert wieder EAX mit 60
9. ok verwechselt is ja EDX NichtOder EDX also EDX negiert quasi
10. überschreibt DX mit systemTime.wSecond
11. Addiert EAX und EDX
12. *multipliziert EAX mit 1000
13. Überschreibt DX mit systemTime.wMilliSeconds
14. addiert EAX und EDX
15. gibt EAX als seed aus
ich hoffe mal ich hab des jetz halberwegs richtig interpretiert ^^
ehm - der wert den der für systemtime einliest (bei 2) - is des in der form HHMMSSII ? - wär schön dann würd ichs kapieren ^^
alzaimar - Di 29.01.08 19:30
Wieso schaut Ihr Euch den Code für Randomize an, wenn es doch eigentlich um die Konstanten des LCG geht? :gruebel:
sataan1337 - Di 29.01.08 19:33
geht net nur um die konstanten sondern um alle werte mit denen er rechnet - btw hast recht die konstanten stehn ja auch noch offen ^^ hatte ich jetz total vergessen
ok kurz mal umdenken ich hab wie gesagt bis jetz nur mim 8085 rumgespielt ^^ - EX und soweiter die register sind 8bit bzw des doppelregister 16 bit oder ? - heisst wenner die 18 (also 18 uhr oder so mal angenommen) nach EAX schreibt wären dann EX = 0000 0000 und AX = 0001 0010 oder? (angenommen der nimmt die Werte als Dezimal)
ok haut hin soweit ^^ (glaub ich zumindest kann sein dass ich iwas durcheinandergenaun hab ^^ - müsst ich nurnoch wissen ob der die Werte vonner Systemzeit als dezimalzahlen nimmt oder als iwas anderes ^^
mit dezimal komm ich für startwerte h=18 m=26 s=12 und i=56 auf nen seed von 32352 ^^
aso und natürlich die konstante aus der gleichung vom LCG^^ - find dazu nix ^^
ehm - idee (bzw sowas ähnliches ^^) - kann das sein dass delphi nur den seed berechnet und dann den rng von windows benutzt? (hab mir sowas sagen lassen ^^)
Timosch - Di 29.01.08 20:37
sataan1337 hat folgendes geschrieben: |
also nochmal für die ganz dummen (also mich ^^)
1. asm
2. LEA EAX,systemTime
3. PUSH EAX
4. CALL GetSystemTime
5. MOVZX EAX,systemTime.wHour
6. IMUL EAX,60
7. ADD AX,systemTime.wMinute { sum = hours * 60 + minutes }
8. IMUL EAX,60
9. XOR EDX,EDX
10 MOV DX,systemTime.wSecond
11 ADD EAX,EDX { sum = sum * 60 + seconds }
12 IMUL EAX,1000
13 MOV DX,systemTime.wMilliSeconds
14 ADD EAX,EDX { sum = sum * 1000 + milliseconds }
15 MOV RandSeed,EAX
1. zu asm find ich nix was der befehl macht ^^
2. eax war des doppelregister oder? bzw systemtime welchen wert läd er da rein?
3. speichert den wert im stack (is mehr ne frage als ne aussage will nur wissen ob ich des richtig auffasse)
4. des getsystemtime is in der system.pas net aufgeführt - aber ich schätz mal der liest sich da die einzelnen variablen ein (second etc)
5. überschreibt EAX mit systemTime.wHour
6. multipliziert den wert mit 60 ?
7. addiert systemTime.wMinute zu AX
8. multipliziert wieder EAX mit 60
9. ok verwechselt is ja EDX NichtOder EDX also EDX negiert quasi
10. überschreibt DX mit systemTime.wSecond
11. Addiert EAX und EDX
12. *multipliziert EAX mit 1000
13. Überschreibt DX mit systemTime.wMilliSeconds
14. addiert EAX und EDX
15. gibt EAX als seed aus
ich hoffe mal ich hab des jetz halberwegs richtig interpretiert ^^
ehm - der wert den der für systemtime einliest (bei 2) - is des in der form HHMMSSII ? - wär schön dann würd ichs kapieren ^^ |
1. schaltet den Inline-Assembler an (Delphi-Hilfe hätte dir das gleiche schneller mitgeteilt...)
2. lädt systemtime in EAX (32-bit-Register)
3. legt EAX auf den Stack
4. Ruft GetSystemTime auf, als Parameter den Inhalt von EAX (weil auf Stack) -> Vermutlich ist systemtime ein leerer Record, der von GetSystemTime gefüllt wird.
5. lädt die Stunden der Systemzeit in EAX
6. multipliziert EAX mit 60
7. lädt in AX (untere 16 Bit von EAX) die Minuten rein -> in EAX steht jetzt also die Systemzeit in Minuten (Stunden*60+Minuten)
8. multipliziert das alles mit 60 (->Sekunden)
9. setzt EDX auf 0 (XOR auf zweimal das gleiche gibt immer 0, geht schneller als MOV EDX,0)
10. lädt in DX die Sekunden
11. zählt sie zu EAX dazu
12. multipliziert EAX mit 1000
13. lädt in DX die Millisekunden
14. addiert sie zu EAX -> in EAX steht jetzt die Systemzeit im Millisekunden
16. schreibt EAX in RandSeed
sataan1337 - Di 29.01.08 21:08
thx erstmal ^^
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mein fehler habs verwechselt *g
Delete - Fr 01.02.08 01:04
elundril hat folgendes geschrieben: |
gute Kryptographiprogramme nehmen was anderes. Z.B.: Irgendwie mit Mauskoordinaten o.ä. So machts jedenfalls ein programm von dem mir der Name gerade nicht einfällt.
lg elundril |
aber das nur, um einen startwert für den zufallszahlengenerator zu kreieren.
in delphi kannst diesen entweder aus der systemzeit setzen lassen oder ihn selbst setzen. das andere sind ein paar konstanten. diese sind IMHO recht gut gewählt. und so liefert der zufallszahlengenerator für die meisten anwendungen ausreichende lange perioden.
sataan1337 - Fr 01.02.08 03:01
wenn diese für dich "recht gut gewählt" sind ^^ - ... - weisst du welche des sind? ^^ - würd mir nen ganzes stückchen weiterhelfen ^^ - was ich momentan "weiss" (oder zumindest annehme ^^) - is dass die formel aus meim ersten post bzw der algorythmus der in den weiteren erläutert wurde stimmen (durch den der seed ermittelt wird) - fehlen aber noch x[n]1 un der faktor ^^ - was dann ja konstanten aus entweder delphi oder windows wären ^^
wenn du da was näheres weisst thx im voraus ^^
Sirke - Fr 01.02.08 09:42
Also, in deiner Formel oben haste dich verschrieben, ein LCG hat die Formel:
Quelltext
1:
| x[n] = ( a * x[n-1] + c ) mod m |
Hierbei wird die maximale Periode durch
M beschränkt, weil ja maximal die Zahlen von
0..M-1 vorkommen können! Die anderen Konstanten
A und
C müssen außerdem bestimmte Bedingungen erfüllen, damit eine maximale Periode ereicht wird.
Ich bin mir nicht sicher, aber
A muss relativ Prim zu
M sein und
C ein vielfaches alles Primfaktoren von
M plus 1! Es gibt aber glaube ich noch andere Punkte die berücksichtigt werden müssen! Der Startwert
x[0] ist eig relativ egal, weil er "nur" festlegt, wo in der Periode gestartet wird!
Hier könnte ich mir vorstellen, dass der Zufallsgenerator anders eingesetzt, nähmlich in der Form:
Quelltext
1: 2:
| x[n] = ( a * x[n-1] + c ) mod m; Output = x[n] mod n; |
Hier ist
N die in
Random() angegebene Zahl, zum festlegen der Menge der Zahlen für den
Output! Ist
M hier eine Primzahl, so lassen sich
A und
C leicht finden und bei einem großen
M bekommt man auch eine lange Periode! Der
Output ist dann durch
N nur noch auf eine bestimmte Menge von Zahlen festgelegt.
Damit ist das errechnen von
A und
C nicht sehr viel schwerer wie bei einem üblichen LCG!
MfG Sirke
Fiete - Fr 01.02.08 13:35
Titel: Re: delphi - zufallsgenerator
Moin,
im Anhang sind noch Zusatzinformationen (doc), das wesentliche hat schon Sirke gepostet.
Als Beispiel ist noch eine Demo dabei.
Gruß
Fiete
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 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!