2008-08-08 19 views
17

Ich weiß, dass nur mit rand() vorhersehbar ist, wenn Sie wissen, was Sie tun, und Zugriff auf den Server haben.Bessere Zufallsgenerierung PHP

Ich habe ein Projekt, das ist hoch abhängig von der Auswahl einer Zufallszahl, die so unvorhersehbar wie möglich ist. Also ich suche nach Vorschlägen, entweder anderen eingebauten Funktionen oder Benutzerfunktionen, die eine bessere Zufallszahl erzeugen können.

verwenden ich dies einen wenig Test zu tun:

$i = 0; 

while($i < 10000){ 
    $rand = rand(0, 100); 

    if(!isset($array[$rand])){ 
     $array[$rand] = 1; 
    } else { 
     $array[$rand]++; 
    } 

    sort($array); 
    $i++; 
} 

I die Ergebnisse gleichmäßig verteilt werden, und es ist ein ungeradees Muster auf die Anzahl, wie oft jede Zahl erzeugt wird.

+0

Es gibt eine neue Funktion in php7, die [genau das tut, was Sie brauchen] (http://stackoverflow.com/a/31444887/1090562). –

Antwort

21

Das Hinzufügen, Multiplizieren oder Abschneiden einer schlechten Zufallsquelle führt zu einem schlechten Zufallsergebnis. Eine Erläuterung finden Sie unter Introduction to Randomness and Random Numbers.

Sie haben Recht mit PHP rand() -Funktion. Eine eindrucksvolle Abbildung finden Sie in der zweiten Abbildung unter Statistical Analysis. (Die erste Zahl ist auffällig, aber sie wurde von Scott Adams gezogen, nicht mit rand() gezeichnet). Eine Lösung ist es, einen echten Zufallsgenerator wie random.org zu verwenden. Ein anderer, wenn Sie Linux/BSD/etc. ist zu verwenden /dev/random. Wenn die Zufälligkeit missionskritisch ist, müssen Sie eine hardware random generator verwenden.

3

Variation auf @KG, mit den Millisekunden seit EPOCH als der Samen für Rand?

+0

Sooooo, mit den heutigen schnellen Multi-Core-Computern haben Sie eine ziemlich gute Chance, den Samen mehrmals wiederzuverwenden? Humongous red flag - du erfindest ein Quadratrad neu, selbst 'srand()' ohne Argumente macht einen besseren ("zufälligeren") Job. – Piskvor

5

random.org verfügt über eine API, auf die Sie über HTTP zugreifen können.

RANDOM.ORG ist ein echter Zufallszahlenservice, der über atmosphärisches Rauschen Zufallszahlen erzeugt.

4

Ich wäre vorsichtig mit dem Eindruck der Zufälligkeit: Es gab viele Experimente, bei denen die Leute die weniger zufällige Verteilung wählen würden. Es scheint, dass der Verstand nicht sehr gut in der Lage ist, Zufälligkeit zu erzeugen oder zu schätzen.

Es gibt gute Artikel über Zufälligkeit bei Fourmilab, einschließlich einer anderen true random generator. Vielleicht könntest du zufällige Daten von beiden Seiten bekommen, wenn du also unten bist, hast du noch die andere.

Fourmilab bietet auch eine test program, um die Zufälligkeit zu überprüfen. Sie können damit Ihre verschiedenen myRand() - Programme überprüfen.

Wie für Ihr letztes Programm, wenn Sie 10000 Werte generieren, warum wählen Sie nicht den endgültigen Wert unter den 10 Tausend? Sie beschränken sich auf eine Teilmenge. Es wird auch nicht funktionieren, wenn Ihre $ min und $ max größer als 10000 sind.

Wie auch immer, die Zufälligkeit, die Sie benötigen, hängt von Ihrer Anwendung ab. rand() ist OK für ein Online-Spiel, aber nicht OK für Kryptographie (alles, was nicht gründlich mit statistischen Programmen getestet wurde, wird sowieso nicht für Kryptographie geeignet sein). Du entscheidest!

2

Eine andere Möglichkeit, Zufallszahlen zu bekommen, vom Konzept her ähnlich 5 UUID

PHP Version zu bekommen.3 und höher

openssl_random_pseudo_bytes(...) 

Oder Sie können die folgende library RFC4122 mit

1

A versuchen, neue PHP7 gibt es eine Funktion, die genau das tut, was man braucht: es erzeugt cryptographically secure pseudo-random integers.

int random_int (int $min , int $max) 

Erzeugt kryptografische zufällige Integer, die für die Verwendung geeignet sind, bei denen unvoreingenommene Ergebnisse kritisch sind (z. B. Mischen eines Pokerdecks).

Für eine genauere Erklärung über PRNG und CSPRNG (und deren Differenz) als auch, warum Ihr ursprünglicher Ansatz ist eigentlich eine schlechte Idee, bitte meine another highly similar answer lesen.