PHP rand() vs. random_int()

Lesezeit: 6 Minuten

Wie php.net gibt an: random_int() Funktion Erzeugt kryptografisch sichere Pseudozufallszahlen.

Aber kann jemand erklären, was der Unterschied zwischen ist rand() & random_int()? Kann ich benutzen random_int() Anstatt von rand() wenn nur eine zufällige Ganzzahl erforderlich ist? Welche ist schneller?

  • php.net/manual/en/function.random-int.php “Gibt ein kryptografisch zurück sicher zufällige ganze Zahl im Bereich von min bis max, einschließlich.” und php.net/manual/en/function.rand.php „Diese Funktion generiert nicht kryptografisch sicher Werte”

    – Funk Forty-Niner

    28. Mai 2017 um 15:08 Uhr

  • de.wikipedia.org/wiki/… — stackoverflow.com/questions/2449594/…

    – Funk Forty-Niner

    28. Mai 2017 um 15:11 Uhr


  • verwenden rand() es sei denn, Sie benötigen eine sicher randomisierte Ganzzahl, dann verwenden Sie random_int(). Wenn Sie nicht wissen, ob Sie letzteres brauchen, tun Sie es wahrscheinlich nicht (es wirkt sich auf die “Ratbarkeit” aus, also stellen Sie sich vor, wo das nützlich ist). Wenn Sie beispielsweise versuchen, eine Diashow zufällig zu erstellen, rand() ist einfach gut.

    – Jared Farrish

    28. Mai 2017 um 15:43 Uhr


  • Was die Geschwindigkeit betrifft, optimieren Sie nicht vorzeitig auf dieser Grundlage, es sei denn, Sie wissen, dass Sie sie brauchen. Konzentrieren Sie sich auf die Anwendung der Funktion und passen Sie später gegebenenfalls die Effizienz an.

    – Jared Farrish

    28. Mai 2017 um 15:47 Uhr

  • mt_rand() ersetzt rand() in PHP7.1. Fragt sich nur, warum das nicht erwähnt wurde?

    – Chuck Le Butt

    19. November 2017 um 23:15 Uhr


Wenn ich mir die Frage noch einmal ansehe und sehe, dass eine Antwort gegeben wurde, finde ich es nur fair, dass ich meine Kommentare zu einer Antwort einreiche, da sie zuvor eingereicht wurden.

Das Handbuch zu PHP 7 random_int() Funktionszustände:

“Gibt eine kryptografisch sichere zufällige Ganzzahl im Bereich von min bis max zurück.”

und für rand()

*Diese Funktion generiert keine kryptografisch sicheren Werte” *

Kommentar von OP:

“@Fred-ii- danke. Aber was bedeutet “kryptografisch sicheres Pseudo-Zufalls”? – NDFA”

Das kann in den folgenden Links nach meinen Erkenntnissen gefunden werden:

Welche Staaten:

Ein kryptografisch sicherer Pseudozufallszahlengenerator (CSPRNG) oder kryptografischer Pseudozufallszahlengenerator (CPRNG)[1] ist ein Pseudozufallszahlengenerator (PRNG) mit Eigenschaften, die ihn für den Einsatz in der Kryptografie geeignet machen.


  • Wie funktioniert ein kryptografisch sicherer Zufallszahlengenerator?

In Bezug auf die Leistung müssen Sie selbst einen Benchmark durchführen.

  • Ich stimme zu. Es ist schön, Ihre Antwort als Referenz hier zu haben (weil ich denke, dass diese Frage mehr Aufmerksamkeit erregen wird, wenn PHP-Entwickler auf 7 umsteigen).

    – behkod

    30. Mai 2017 um 19:30 Uhr

  • In der Tat @NDFA Prost

    – Funk Forty-Niner

    30. Mai 2017 um 20:32 Uhr

Benutzer-Avatar
Matt Janssen

Ab PHP 7.1, rand() ist ein Alias ​​für mt_rand(). Die neueren random_int() ist die langsamste, aber einzige sichere Methode der drei.

<?php

$start = microtime(true);
$sum = 0.0;
for ($i = 0; $i < 10000000; $i++) {
    $sum += rand(0, 32767);
}
printf('[rand] Time: %.3f s%s', microtime(true) - $start, PHP_EOL);

$start = microtime(true);
$sum = 0.0;
for ($i = 0; $i < 10000000; $i++) {
    $sum += mt_rand(0, 32767);
}
printf('[mt_rand] Time: %.3f s%s', microtime(true) - $start, PHP_EOL);

$start = microtime(true);
$sum = 0.0;
for ($i = 0; $i < 10000000; $i++) {
    $sum += random_int(0, 32767);
}
printf('[random_int] Time: %.3f s%s', microtime(true) - $start, PHP_EOL);

Ergebnisse auf PHP 7.4:

[rand] Time: 0.320 s      
[mt_rand] Time: 0.326 s   
[random_int] Time: 9.255 s

rand()

rand() ist jetzt ein Alias ​​für mt_rand(). Mit Blick auf die Quellcode von mt_rand(), ist ersichtlich, dass die Zufallszahl überhaupt nicht zufällig ist. Es ist eine einfache mathematische Berechnung, die nicht viel komplexer ist als

return $min + suffle_bits($internal_counter++) % ($max - $min);

wo suffle_bits() ist eine vorhersehbare binäre Arithmetik, um es so aussehen zu lassen $internal_counter erhöht sich nicht nur selbst.

Deshalb rand() soll zurückkommen pseudozufällig Zahlen. Die zurückgegebenen Zahlen scheinen zufällig gezogen zu sein, kennen aber den Wert der $internal_counter lässt Sie vorhersagen, was folgen wird.

random_int()

random_int() leidet nicht unter diesem Vorhersagbarkeitsproblem, vorausgesetzt, der Entropiegenerator des Computers ist richtig vorbereitet.

Das Erraten des nächsten Wertes ist selbst dann nicht möglich, wenn ein Angreifer sehr viele Werte sammelt.

Welches ist am besten

Wenn ein Angreifer den Wert erraten kann $internal_counter aus der Ausgabe Ihres Codes und verwenden Sie dieses Wissen, um den beabsichtigten Zweck Ihres Codes zu beeinträchtigen und dann zu verwenden random_int().

Wenn die Zufallszahl verwendet wird, um beispielsweise eine zufällige Begrüßung anzuzeigen, dann rand() ist absolut sicher.

Wenn nun eine lange Liste von GUIDs oder Barcodes generiert werden muss und der Endbenutzer nicht in der Lage sein darf, einen anderen gültigen Wert aus einer Teilmenge zu erraten, dann random_int() ist nicht nur aus Sicherheitsgründen besser, sondern auch, weil es sich nicht wiederholt. rand() kann sich je nach Plattform so schnell wie die Ausgabe von 32768 wiederholen.

Welches ist schneller

Ohne jeden Zweifel, rand() ist einfacher und damit schneller.

Hier ist ein grober, einzeiliger, einfach zu kopierender und einzufügender Befehl, um zu zählen, aus wie vielen Zahlen gezogen werden kann rand() in 10 sekunden:

php -r '$s=microtime(true);$c=0;while(microtime(true)-$s<10){rand(0,9);$c++;};echo "$c\n";'

Und das gleiche für random_int():

php -r '$s=microtime(true);$c=0;while(microtime(true)-$s<10){random_int(0,9);$c++;};echo "$c\n";'

Die Zähler für PHP 7.3 sind:

rand():       36665142
random_int(): 10511327

rand() ist weniger als 4 mal schneller. Wenn Geschwindigkeit kein Problem ist, random_int() ist der richtige Weg, aber für die grundlegendsten, nicht kritischen Missionen.

Wie bei den meisten Zahlengeneratoren ist die Verwendung von rand() nicht sicher, da sie keine kryptografisch sicheren Werte generiert und die Ausgabe von rand() vorhersehbar ist.

PHP 7.0 führt random_bytes und random_int als Kernfunktionen ein, die frei von den Problemen sind, die die meisten Zufallszahlengeneratoren haben.

Benutzer-Avatar
Raffael Kühn

Ergänzende Frédéric-Antwort in PHP 8.0.3, random_int() scheint viel schneller zu sein als zuvor, wenn man sein eigenes Codebeispiel verwendet.

mit:

<?php
    echo "this will take 20 seconds\n\n";
    
    echo "generating random with 'rand' method\n";
    $s1=microtime(true);$c1=0;while(microtime(true)-$s1<10){rand(0,65535);$c1++;};
    $fc1 = number_format($c1 , 0, ',', '.');
    echo "generated: $fc1\n\n";
    
    echo "generating random with 'random_int' method\n";
    $s2=microtime(true);$c2=0;while(microtime(true)-$s2<10 {random_int(0,65535);$c2++;};
    $fc2 = number_format($c2 , 0, ',', '.');
    echo "generated: $fc2\n\n"; 
?>

Ich habe die Ausgabe:

this will take 20 seconds

generating random with 'rand' method
generated: 48.423.988

generating random with 'random_int' method
generated: 30.843.067

bei seinen Prüfungen, random_int() war mehr als dreimal langsamer als rand().

in diesen, random_int() ist nur etwa 40% langsamer als rand().

PS: Ich habe den maximalen Zufallswert für den persönlichen Gebrauch von 9 auf 65535 erhöht, scheint die Geschwindigkeit in beiden Fällen tatsächlich erhöht zu haben.

Benutzer-Avatar
Ion

Ich habe persönlich keine Probleme mit random_int festgestellt, aber es sollte mit try/catch verwendet werden, da es eine Ausnahme auslöst, wenn es nicht möglich war, genügend Entropie zu sammeln.

1246780cookie-checkPHP rand() vs. random_int()

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy