Maison  >  Article  >  développement back-end  >  Les vrais et faux nombres aléatoires de PHP

Les vrais et faux nombres aléatoires de PHP

*文
*文original
2017-12-27 10:23:382683parcourir

Cet article présente principalement l'explication détaillée des nombres pseudo-aléatoires et des vrais nombres aléatoires en PHP. Cet article explique d'abord les concepts liés aux vrais nombres aléatoires et aux nombres pseudo-aléatoires, et donne un meilleur nombre pseudo-aléatoire que l'utilisation du. Fonction mt_rand(). Un exemple de code. J'espère que cela aide tout le monde.

La première chose à préciser est que les ordinateurs ne génèrent pas de nombres absolument aléatoires. Les ordinateurs ne peuvent générer que des « nombres pseudo-aléatoires ». En fait, les nombres absolument aléatoires ne sont que des nombres aléatoires idéaux. Quelle que soit la manière dont l’ordinateur se développe, il ne générera pas une chaîne de nombres absolument aléatoires. Les ordinateurs ne peuvent générer que des nombres relativement aléatoires, c’est-à-dire des nombres pseudo-aléatoires.

Les nombres pseudo-aléatoires ne sont pas des nombres pseudo-aléatoires. Le « pseudo » signifie ici régulier, ce qui signifie que les nombres pseudo-aléatoires générés par les ordinateurs sont à la fois aléatoires et réguliers. Comment le comprendre ? Les nombres pseudo-aléatoires générés suivent parfois certaines règles, et parfois ils ne suivent aucune règle ; certains des nombres pseudo-aléatoires suivent certaines règles ; Par exemple, "Il n'y a pas deux feuilles de même forme dans le monde." Cela indique les caractéristiques des choses, c'est-à-dire le hasard, mais les feuilles de chaque arbre ont des formes similaires, ce qui est le point commun des choses, c'est-à-dire. , régularité. De ce point de vue, vous accepterez probablement le fait que les ordinateurs ne peuvent générer que des nombres pseudo-aléatoires mais ne peuvent pas générer de nombres absolument aléatoires.

Tout d’abord, comprenons les concepts de vrais nombres aléatoires et de nombres pseudo-aléatoires.

Vrais générateurs de nombres aléatoires : Anglais : les vrais générateurs de nombres aléatoires, en abrégé : TRNG, sont des nombres aléatoires générés par des méthodes physiques imprévisibles.

Générateurs de nombres pseudo-aléatoires : Anglais : les générateurs de nombres pseudo-aléatoires, en abrégé : PRNG, sont générés par des ordinateurs à l'aide de certains algorithmes.

Comparez les images de nombres aléatoires générés par les deux méthodes.

Bitmap aléatoire généré par Random.org (qui utilise le bruit atmosphérique, généré par les orages dans l'air) :

Images aléatoires générées par le rand () fonction de PHP sous Windows :

Evidemment, les images générées par ce dernier générateur de nombres pseudo-aléatoires présentent ces rayures évidentes.

Le code permettant d'utiliser la fonction aléatoire rand de PHP pour générer cette image est :

//需要开启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);


En fait, tous les générateurs de nombres pseudo-aléatoires (PRNG) n'ont pas cet effet. Ce qui est mauvais, c'est que la fonction rand() de PHP sous Windows se trouve être comme ça. Si le même code est testé sous Linux, l'image résultante ne montrera pas de rayures évidentes. Sous Windows, si la fonction mt_rand() est utilisée à la place de la fonction rand(), l'effet sera bien meilleur. En effet, mt_rand() utilise l'algorithme Mersenne Twister pour générer des nombres aléatoires. La documentation PHP dit également : mt_rand() peut générer des valeurs aléatoires en moyenne quatre fois plus rapidement que le rand() fourni par la libc.

De plus, le noyau Linux (1.3.30 et supérieur) inclut un générateur de nombres aléatoires /dev/random, qui est suffisant pour de nombreuses raisons de sécurité.

Ce qui suit est une introduction aux principes du générateur de nombres aléatoires de Linux :

Le système d'exploitation Linux fournit des bibliothèques qui sont intrinsèquement aléatoires (ou au moins ont des composants avec une forte caractère aléatoire). Ces données proviennent généralement du pilote de périphérique. Par exemple, un pilote de clavier collecte des informations sur le temps écoulé entre deux pressions sur une touche, puis insère ce bruit ambiant dans une bibliothèque de générateurs de nombres aléatoires.

Les données aléatoires sont stockées dans un pool d'entropie (le noyau Linux maintient un pool d'entropie pour collecter le bruit ambiant des pilotes de périphériques et d'autres sources. En théorie, les données du pool d'entropie sont complètement aléatoires et peuvent être générées A séquence de vrais nombres aléatoires. Pour suivre le caractère aléatoire des données dans le pool d'entropie, le noyau estime le caractère aléatoire des données lors de leur ajout au pool. Ce processus est appelé estimation de l'entropie. dans le pool. Une valeur plus élevée indique plus de caractère aléatoire dans les données du pool), qui sont "remuées" à chaque fois que de nouvelles données arrivent. Cette agitation est en réalité une transformation mathématique qui contribue à améliorer le caractère aléatoire. Au fur et à mesure que les données sont ajoutées au pool d'entropie, le système estime le nombre de bits véritablement aléatoires qu'il a obtenus.

Il est important de mesurer la quantité totale de hasard. Le problème est que certaines quantités sont souvent moins aléatoires qu’il n’y paraît au premier abord. Par exemple, l'ajout d'un nombre de 32 bits représentant le nombre de secondes écoulées depuis la dernière frappe ne fournissait pas réellement une nouvelle information aléatoire de 32 bits, puisque la plupart des frappes sont rapprochées.

Une fois les octets lus depuis /dev/random, le pool d'entropie effectue un hachage cryptographique à l'aide de l'algorithme MD5, et les octets individuels du hachage sont convertis en nombres et renvoyés.

S'il n'y a pas de bits aléatoires disponibles dans le pool d'entropie, /dev/random attend qu'il y ait suffisamment de bits aléatoires dans le pool, sans renvoyer de résultat. Cela signifie que si vous utilisez /dev/random pour générer de nombreux nombres aléatoires, vous constaterez que c'est trop lent pour être pratique. Nous voyons souvent /dev/random générer des dizaines d’octets de données puis ne produire aucun résultat pendant plusieurs secondes.

幸运的是有熵池的另一个接口可以绕过这个限制:/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教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn