Trotz des merkwürdigen Titels möchte ich eine berechtigte Frage stellen: Welche generierten Zahlen sind mehr zufällig : Java Random()
class oder Math.random()
oder C ++ rand()
?
Ich habe gehört, dass PHP rand()
ziemlich schlecht ist, d. h., wenn Sie seine Ergebnisse zuordnen, können Sie deutlich ein Muster sehen; Leider weiß ich nicht, wie man eine Karte in C ++ oder Java zeichnet.
Auch, nur aus Interesse, was ist mit C #?
Sowohl Java als auch C ++ erzeugen Pseudozufallszahlen, die entweder:
sindGanz ehrlich, außer Sie sind in einer dieser Klassen, sind Pseudozufallszahlengeneratoren in Ordnung.
Java hat auch SecureRandom
, das vorgibt, Kryptoklassen-Nicht-Determinismus bereitzustellen (ich kann die Richtigkeit dieses Arguments nicht kommentieren), und C ++ hat jetzt eine viel breitere Auswahl an Zufallszahlen als nur rand()
- Einzelheiten finden Sie unter <random>
.
Bestimmte Betriebssysteme können Entropiequellen für Zufallsgeneratoren wie CryptGenRandom
bereitstellen unter Windows oder lesen /dev/random
unter Linux. Alternativ können Sie die Entropie durch zufällige Ereignisse wie das Timing der Benutzereingabe hinzufügen.
(a) Darf tatsächlich Spuren anderer Jobtypen enthalten, die nicht Statistiker oder Kryptograph sind: -)
java.util.Random
(was intern von Math.random()
verwendet wird) verwendet einen linearen Kongruenzgenerator , der ein ziemlich großer ist schwache RNG, aber genug für einfache Dinge. Für wichtige Anwendungen sollte stattdessen java.security.SecureRandom
verwendet werden.
Ich glaube nicht, dass die C- oder C ++ - Sprachspezifikationen den Algorithmus für rand()
verbieten, aber die meisten Implementierungen verwenden auch eine LCG. C ++ 11 hat neue APIs hinzugefügt, die eine höhere Zufälligkeit bieten.
Es gibt ein sehr gutes Dokument im Internet, das von einem der weltweiten Experten für Zufallszahlengeneratoren erstellt wurde.
Der erste Teil des Dokuments ist eine Beschreibung der Tests, die Sie möglicherweise überspringen, wenn Sie nicht wirklich interessiert sind. Ab Seite 27 gibt es die Ergebnisse der verschiedenen Tests für viele Generatoren, einschließlich Java, C ++, Matlab, Mathematica, Excel, Boost, ... (Sie werden im Text beschrieben).
Es scheint, dass der Generator von Java ein bisschen besser ist, aber beide gehören nicht zu den besten der Welt. Das MT19937 von C ++ 11 ist schon viel besser.
PHP verwendet einen Seed. Wenn der Seed zu zwei verschiedenen Zeiten gleich ist, gibt die rand () -Funktion IMMER dasselbe aus. (Was zum Beispiel für Token ziemlich schlecht sein kann). Ich weiß nicht für C ++ und Java, aber es gibt keine echte Zufälligkeit, was die Qualität schwierig zu bewerten macht. Sicherheit darf sich nicht auf solche Funktionen verlassen.
Ich bin mir keiner Sprache bewusst, in der Zufallszahlen wirklich zufällig sind - ich bin mir sicher, dass so etwas existiert, aber im Allgemeinen ist es "Du steckst einen Samen hinein und du erhältst die Sequenz, die der Samen gibt". Was ist in Ordnung, wenn Sie ein einfaches Shootem-Up-Spiel machen wollen, ein einfaches Poker-Spiel, Roulette-Simulator für den Heimgebrauch usw. Aber wenn Sie Geld haben, verlassen Sie sich darauf, dass das Spiel wirklich zufällig ist (zB geben Sie Geld aus basierend auf den Ergebnissen bestimmter Sequenzen) oder Ihre geheimen Dateien verlassen sich auf Ihre Zufallszahlen, dann benötigen Sie definitiv einen anderen Mechanismus zum Finden von Zufallszahlen.
Und es gibt einige "echte" Zufallszahlengeneratoren. Sie liefern keinen Seed, also ist die Vorhersagbarkeit auf der Basis der Anzahl (n), die du beim letzten Mal erhalten hast, gering. Ich sage nicht, dass es Null ist, weil ich nicht sicher bin, ob man das auch durch das Abtasten von Radiowellen bei einer unbenutzten Radiofrequenz, radioaktivem Zerfall oder was auch immer die neueste Methode zum Erzeugen echter Zufallszahlen ist.