Heim  >  Artikel  >  Backend-Entwicklung  >  Die wahren und falschen Zufallszahlen von PHP

Die wahren und falschen Zufallszahlen von PHP

*文
*文Original
2017-12-27 10:23:382603Durchsuche

Dieser Artikel führt hauptsächlich die detaillierte Erklärung von Pseudozufallszahlen und echten Zufallszahlen in PHP ein. Dieser Artikel erläutert zunächst die verwandten Konzepte von echten Zufallszahlen und Pseudozufallszahlen und gibt eine bessere Pseudozufallszahl als die Verwendung mt_rand()-Funktion. Ein Beispielcode. Ich hoffe, es hilft allen.

Das erste, was gesagt werden muss, ist, dass Computer keine absoluten Zufallszahlen erzeugen können. Computer können nur „Pseudozufallszahlen“ erzeugen. Tatsächlich sind absolute Zufallszahlen nur ideale Zufallszahlen, egal wie sich der Computer entwickelt, er wird keine Folge absolut zufälliger Zahlen erzeugen. Computer können nur relativ zufällige Zahlen, also Pseudozufallszahlen, erzeugen.

Pseudozufallszahlen sind keine Pseudozufallszahlen. Das „Pseudo“ bedeutet hier regulär, was bedeutet, dass die von Computern generierten Pseudozufallszahlen sowohl zufällig als auch regelmäßig sind. Wie ist es zu verstehen? Die generierten Pseudozufallszahlen folgen manchmal bestimmten Regeln, manchmal folgen sie keinen Regeln; einige der Pseudozufallszahlen folgen bestimmten Regeln; Zum Beispiel: „Es gibt keine zwei Blätter mit der gleichen Form auf der Welt.“ Dies weist auf die Eigenschaften der Dinge hin, das heißt auf Zufälligkeit, aber die Blätter jedes Baumes haben ähnliche Formen, was auf die Gemeinsamkeit der Dinge zurückzuführen ist , Regelmäßigkeit. Aus dieser Perspektive werden Sie wahrscheinlich die Tatsache akzeptieren, dass Computer nur Pseudozufallszahlen, aber keine absoluten Zufallszahlen generieren können.

Lassen Sie uns zunächst die Konzepte echter Zufallszahlen und Pseudozufallszahlen verstehen.

Echte Zufallszahlengeneratoren: Englisch: Echte Zufallszahlengeneratoren, abgekürzt als: TRNGs, sind Zufallszahlen, die durch unvorhersehbare physikalische Methoden generiert werden.

Pseudozufallszahlengeneratoren: Englisch: Pseudozufallszahlengeneratoren, abgekürzt als: PRNGs, werden von Computern mithilfe bestimmter Algorithmen generiert.

Vergleichen Sie die Bilder von Zufallszahlen, die mit den beiden Methoden generiert wurden.

Zufällige Bitmap, generiert von Random.org (die atmosphärisches Rauschen nutzt, das durch Gewitter in der Luft erzeugt wird):

Zufällige Bilder, generiert vom Rand ()-Funktion von PHP unter Windows:

Offensichtlich weisen die vom letztgenannten Pseudozufallszahlengenerator erzeugten Bilder diese offensichtlichen Streifen auf.

Der Code zur Verwendung der Rand-Zufallsfunktion von PHP zum Generieren dieses Bildes lautet:

//需要开启gd库
header("Content-type: image/png");
$im = imagecreatetruecolor(512, 512)
or die("Cannot Initialize new GD image stream");
$white = imagecolorallocate($im, 255, 255, 255);
for ($y=0; $y<512; $y++) {
for ($x=0; $x<512; $x++) {
if (rand(0,1) === 1) {
imagesetpixel($im, $x, $y, $white);
}
}
}
imagepng($im);
imagedestroy($im);


Tatsächlich haben nicht alle Pseudozufallszahlengeneratoren (PRNGs) diesen Effekt Schlecht ist, dass die rand()-Funktion von PHP unter Windows zufällig so ist. Wenn derselbe Code unter Linux getestet wird, weist das resultierende Bild keine offensichtlichen Streifen auf. Wenn unter Windows die Funktion mt_rand() anstelle der Funktion rand() verwendet wird, ist der Effekt viel besser. Dies liegt daran, dass mt_rand() den Mersenne Twister-Algorithmus verwendet, um Zufallszahlen zu generieren. In der PHP-Dokumentation heißt es außerdem: mt_rand() kann Zufallswerte im Durchschnitt viermal schneller generieren als rand(), das von libc bereitgestellt wird.

Darüber hinaus enthält der Linux-Kernel (1.3.30 und höher) einen Zufallszahlengenerator /dev/random, der für viele Sicherheitszwecke ausreichend ist.

Das Folgende ist eine Einführung in die Prinzipien des Linux-Zufallszahlengenerators:

Das Linux-Betriebssystem bietet Bibliotheken, die von Natur aus zufällig sind (oder zumindest Komponenten mit starken Komponenten haben). Zufälligkeit) Daten. Diese Daten stammen normalerweise vom Gerätetreiber. Beispielsweise sammelt ein Tastaturtreiber Informationen über die Zeit zwischen zwei Tastendrücken und füllt diese Umgebungsgeräusche dann in eine Zufallszahlengeneratorbibliothek ein.

Zufällige Daten werden in einem Entropiepool gespeichert (der Linux-Kernel verwaltet einen Entropiepool, um Umgebungsgeräusche von Gerätetreibern und anderen Quellen zu sammeln. Theoretisch sind die Daten im Entropiepool völlig zufällig und können generiert werden Um die Zufälligkeit der Daten im Entropiepool zu verfolgen, schätzt der Kernel die Zufälligkeit der Daten beim Hinzufügen zum Pool. Dieser Vorgang wird als Entropieschätzung bezeichnet Ein größerer Wert bedeutet mehr Zufälligkeit in den Daten im Pool, die jedes Mal „gerührt“ werden, wenn neue Daten eingehen. Dieses Rühren ist eigentlich eine mathematische Transformation, die zur Verbesserung der Zufälligkeit beiträgt. Wenn dem Entropiepool Daten hinzugefügt werden, schätzt das System, wie viele wirklich zufällige Bits es erhalten hat.

Es ist wichtig, den Gesamtbetrag der Zufälligkeit zu messen. Das Problem besteht darin, dass manche Größen oft weniger zufällig sind, als sie auf den ersten Blick erscheinen. Das Hinzufügen einer 32-Bit-Zahl, die die Anzahl der Sekunden seit dem letzten Tastendruck darstellt, lieferte beispielsweise keine neue 32-Bit-Zufallsinformation, da die meisten Tastenanschläge nahe beieinander liegen.

Sobald die Bytes aus /dev/random gelesen wurden, führt der Entropiepool mithilfe des MD5-Algorithmus einen kryptografischen Hash durch und die einzelnen Bytes im Hash werden in Zahlen umgewandelt und zurückgegeben.

Wenn im Entropiepool keine Zufälligkeitsbits verfügbar sind, wartet /dev/random, bis genügend Zufälligkeiten im Pool vorhanden sind, ohne ein Ergebnis zurückzugeben. Das heißt, wenn Sie /dev/random verwenden, um viele Zufallszahlen zu generieren, werden Sie feststellen, dass es zu langsam ist, um praktisch zu sein. Wir sehen oft, dass /dev/random Dutzende Bytes an Daten generiert und dann viele Sekunden lang keine Ergebnisse liefert.

幸运的是有熵池的另一个接口可以绕过这个限制:/dev/urandom。即使熵池中没有随机性可用,这个替代设备也总是返回随机数。如果您取出许 多数而不给熵池足够的时间重新充满,就再也不能获得各种来源的合用熵的好处了;但您仍可以从熵池的 MD5 散列中获得非常好的随机数!这种方式的问题是,如果有任何人破解了 MD5 算法,并通过查看输出了解到有关散列输入的信息,那么您的数就会立刻变得完全可预料。大多数专家都认为这种分析从计算角度来讲是不可行的。然而,仍然认为 /dev/urandom 比 /dev/random 要“不安全一些”(并通常值得怀疑)。

Windows下没有/dev/random可用,但可以使用微软的“capicom.dll”所提供的CAPICOM.Utilities 对象。

以下是使用PHP时比用mt_rand()函数产生更好的伪随机数的一段例子代码:

<?php
// get 128 pseudorandom bits in a string of 16 bytes

$pr_bits = &#39;&#39;;

// Unix/Linux platform?
$fp = @fopen(&#39;/dev/urandom&#39;,&#39;rb&#39;);
if ($fp !== FALSE) {
$pr_bits .= @fread($fp,16);
@fclose($fp);
}

// MS-Windows platform?
if (@class_exists(&#39;COM&#39;)) {
try {
$CAPI_Util = new COM(&#39;CAPICOM.Utilities.1&#39;);
$pr_bits .= $CAPI_Util->GetRandom(16,0);

// if we ask for binary data PHP munges it, so we
// request base64 return value. We squeeze out the
// redundancy and useless ==CRLF by hashing...
if ($pr_bits) { $pr_bits = md5($pr_bits,TRUE); }
} catch (Exception $ex) {
// echo &#39;Exception: &#39; . $ex->getMessage();
}
}

if (strlen($pr_bits) < 16) {
// do something to warn system owner that
// pseudorandom generator is missing
}
?>

所以PHP要产生真随机数 还是要调用外部元素来支持的!

相关推荐:

PHP 随机数 C扩展随机数

基于php 随机数的深入理解

PHP函数:生成N个不重复的随机数,php 随机数_PHP教程

Das obige ist der detaillierte Inhalt vonDie wahren und falschen Zufallszahlen von PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn