Also wenn ich http://de.wikipedia.org/wiki/Pseudozufallszahl im Zusammenhang mit den bisherigen Aussagen richtig interpretiere, dann generiert FPC bei gleichen Startwert (Seed) immer die gleichen Zufallszahlen. Diese Funktion ist, basierend auf dem Startwert, effizient berechenbar, ohne diesen aber nicht. Effizient berechenbar heißt hierbei, dass es einen Algorithmus gibt, der die Funktion in einer Zeit t hoch c berechnen kann, wobei c konstant ist. Nicht effizient hieße t steht im Exponenten. Bei einem weiteren Besuch auf http://en.wikipedia.org/wiki/Mersenne_twister bzw. der deutschen Version dieser Seite, habe ich dann auch gefunden, dass der Algorithmus eine sehr gute Gleichverteilung liefert (das englische k-distribution hat mir nichts gesagt).
Ergo:
Wer einfach eine ohne den Startwert unvorhersagbare und über etwa 6000 Dezimalstellen gleichverteilte Zahlenfolge braucht, für den liefert 1x randomize + beliebig oft (auch in einer Schleife direkt hintereinander) angewandtes random das gewünschte Ergebnis.
Wer unbedingt echte Zufallszahlen braucht (z.B. für die Vergabe von Banking-PINs oder sowas), sollte vor jedem random eine Zeit abwarten, dessen Länge durch eine Benutzerinteraktion oder etwas ähnlich zeitlich unvorhersehbares (nicht random!) bestimmt wird und 1x randomize aufrufen (oder kann man die seed auch anders als über die Zeit setzen?).
Bei mir steht unter Randomize() "randseed:=longint(Fptime(nil));", was auf syscall_nr_gettimeofday() verweist.
Um auch mein Halbwissen in diese Diskussion einzubringen: AFAIK waren es 2^15 verschiedene Werte unter TP gewesen. Die Begrenzung entsteht IMHO aus einer Modulo-Verrechnung. Vom Prinzip her: random:=random * x mod y. Allerdings gibt es beim Mersenne-Twister (genrand_MT19937) nur ein wildes xor, and, shift Verschieben, das auf einen Blick zu verstehen, einen höheren IQ als meinen bedarf. Dafür steht folgendes im Quellcode:
What is Mersenne Twister?
Mersenne Twister(MT) is a pseudorandom number generator developped by
Makoto Matsumoto and Takuji Nishimura (alphabetical order) during
1996-1997. MT has the following merits:
It is designed with consideration on the flaws of various existing
generators.
Far longer period and far higher order of equidistribution than any
other implemented generators. (It is proved that the period is 2^19937-1,
and 623-dimensional equidistribution property is assured.)
Fast generation. (Although it depends on the system, it is reported that
MT is sometimes faster than the standard ANSI-C library in a system
with pipeline and cache memory.)
Efficient use of the memory. (The implemented C-code mt19937.c
consumes only 624 words of working area.)
lrlr hat geschrieben:und ist damit NICHT threadsafe..
wer (bei borland) hat denn DAS verbrochen ?????
Die ganze Borland VCL ist AFAIK nicht threadsafe ausgelegt.
@Scotty: GetTickCount ist ein WinAPI-Aufruf, der die Zeit seit Systemstart in ms zurückgibt. Nach 49,7 Tagen läuft der über (in der 32bit Version der Funktion). Folglich musst du in deinem nicht-Win-Betriebssystem eine andere Implementierung haben.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
Wenn Borland (oder wie sie jetzt auch heißen mögen) das "verbricht", ist das eine Sache, warum FPC es nicht besser macht, wenn schon ein inkompatibles random/randseed implementiert wird, ist schon weniger amüsant.
Noch schlimmer ist jedoch, daß sie nicht nur randseed nicht threadsafe machen bzw. mehrfach/gleichzeitig benutzbar (das könnte man halbwegs hinbiegen, wenn man den alten Wert rettet und wieder herstellt), aber beim MT besteht der Kontext aus 624 longints + Indix. Außerdem ist das Umsetzen von randseed durch einen "Hack" (siehe genrand_MT19937 in system.inc) quasi ausgehebelt.
Wir könnten ja einen besseren Random erstellen. Im Übringen ist die LCL auch nicht Thread sicher. Was auch durchaus einen Sinn ergibt.
Die Frage währe: Könnte man eine Funktion schreiben, die echte Randomzahlen ausgibt ? In Linux gibt es eine Datei die mit "Zufällige" zahlen gefüllt wurden sind, aber ob das was nützt ?
pluto hat geschrieben:Die Frage währe: Könnte man eine Funktion schreiben, die echte Randomzahlen ausgibt ?
Die Antwort: nein. Alles, was Rechner berechnen können ist ja berechenbar und somit nicht echt zufällig. Die Zahlen in der Datei sind durch ihre Speicherung nun auch bekannt und nicht mehr zufällig. Der Zufallszahlenalgorithmus ist schon okay so, wie er ist. Bestenfalls die Threadsicherheit könnte man offenbar verbessern.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
Dann müsst er so aufgebaut sein das er sie nicht Berechnet sondern Ermittelt. Die frage währe halt nur wie. Somit gibt es keinen Echten Zufalls zahlen. Eigentlich schade. Mir reicht jedoch der Standard Random voll und ganz.
Hab ich oben schon geschrieben: In Abhängigkeit von irgendwelchen Benutzereingaben (Mausposition oder irgendwelche hochaufgelöste Reaktionszeiten des Benutzers als Seed). Aber das kannst du nur in Ausnahmefällen realisieren. Im Normalfall ist es auch einfach nicht nötig.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
RSE hat geschrieben:Hab ich oben schon geschrieben: In Abhängigkeit von irgendwelchen Benutzereingaben (Mausposition oder irgendwelche hochaufgelöste Reaktionszeiten des Benutzers als Seed). Aber das kannst du nur in Ausnahmefällen realisieren. Im Normalfall ist es auch einfach nicht nötig.
m Normalfall reichen ja auch Pseudozufallszahlen aus. In der Regel reichen auch Pseudezufallszahlen mit einem echt zufälligen Startwert aus. Das heißt weiter Random() benutzen und vorher einen Wert für randseed aus /dev/random lesen. Für Linux sind die Zahlen auch über einen Reboot sicher (der Inhalt wird gespeichert), solange der Angreifer keinen Root-Zugriff auf die Datei hat (sollte auf einem System, das unbedingt diese Sicherheit bei den Zufallszahlen bieten muss, selbstverständlich sein).
Unter Windows weiß ich leider nicht, wie man entsprechende echte Zufallszahlen beziehen kann; die eigenständige Generation über Maus-/Tastatureingabe ist aber sicherlich möglich (auch wenn ich nicht weiß, inwiefern das innerhalb der RTL gelöst werden könnte).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein