web-dev-qa-db-fra.com

Comment fonctionnent les générateurs de nombres aléatoires?

Je réfléchissais simplement à la fonction php Rand(), et je pensais à comment je pouvais le refaire, et je suis tombé complètement stupéfait.

Comment fonctionnent les générateurs de nombres aléatoires?

24
Korvin Szanto

Les générateurs de nombres aléatoires (RNG) génèrent vraiment des nombres pseudo-aléatoires, car il est impossible de générer réellement un nombre vraiment aléatoire. Les seules choses vraiment vraiment aléatoires sont les actes de Dieu, comme la foudre.

Cet article wikipedia pourrait vous aider dans l'explication: http://en.wikipedia.org/wiki/Random_number_generators


D'après ce que je comprends, il y a essentiellement deux parties d'un RNG: la graine, puis le nombre aléatoire choisi dans cette graine. Lorsque vous amorcez le RNG, vous lui donnez un équivalent à un point de départ. Ce point de départ a alors un tas de nombres qui sont "à l'intérieur" de celui que le programme choisit. En PHP, vous pouvez utiliser srand () pour "mélanger" les graines, donc vous obtenez presque toujours une réponse différente. Vous pouvez ensuite utiliser Rand (min, max) pour entrer dans la graine et choisir un nombre entre le min et le max, inclus.


AVERTISSEMENT, ANALOGIE AU FROMAGE POSSIBLE À VENIR!

Considérez chaque "graine" comme une glacière, puis les nombres aléatoires comme des glaçons. Disons que vous avez 1000 coffres à glace et que chaque coffre contient 1000 cubes de glace à l'intérieur. À la foire du comté, ils choisiront une glacière pour commencer à utiliser pour les boissons, et ils ne peuvent utiliser qu'un seul glaçon. Cependant, ils n'ont besoin que de glaçons de plus de 1 pouce cube. Ils choisiront donc un coffre au hasard parmi ces 1000 coffres, puis ils choisiront un cube de glace à l'intérieur de ce coffre au hasard. Si cela fonctionne pour la taille souhaitée, ils l'utilisent. Si ce n'est pas le cas, ils le remettent dans la poitrine avec les autres. S'ils veulent le rendre un peu plus amusant, ils changent de coffre à l'avance pour une totale inconscience, si vous voulez!

Quant à savoir comment PHP choisit réellement la graine et le nombre aléatoire, je n'ai pas assez de connaissances pour cela (ce qui est probablement ce que vous vous demandiez le plus!). Je ne le ferais pas essayez de refaire la fonction Rand (); pour la plupart des applications Web que vous allez créer, Rand () devrait suffire pour tout nombre aléatoire dont vous aurez besoin.

Consultez également les générateurs congruentiels linéaires, cela pourrait être plus de ce que vous recherchez si vous voulez les détails sales: http://en.wikipedia.org/wiki/Linear_congruential_generator

J'espère que cela t'aides!

7
Mr. Starburst

Ils ne sont généralement pas vraiment aléatoires, mais sont appelés pseudo-aléatoires car ils génèrent une séquence de nombres qui semble aléatoire. Cela se fait avec des formules mathématiques intéressantes. L'un des plus courants est le Linear Congruential Generator .

Les nombres pseudo-aléatoires ont une propriété utile que les vrais nombres aléatoires n'ont pas: si vous utilisez la même graine lorsque vous commencez, vous récupérerez une séquence identique. Cela peut être très pratique pour les tests.

18
Mark Ransom

Demandez-vous pseudo-aléatoire ou aléatoire? D'autres ont répondu au sujet du pseudo-aléatoire, permettez-moi de parler de aléatoire.

Il y avait (sont?) De véritables générateurs de nombres aléatoires à base de matériel en vente. Ils étaient basés sur une puce avec une petite radio mesurant le bruit blanc du rayonnement de l'espace lointain, ou un petit échantillon radioactif et mesurant les périodes entre sa désintégration. Le problème avec eux était la bande passante - la quantité d'entropie qu'ils pouvaient générer n'était pas très élevée, ils ont donc été utilisés pour des germes d'algorithmes pseudo-aléatoires. Ils étaient utilisés dans les systèmes bancaires, la haute sécurité et autres.

OTOH, si vous rencontrez un développeur de systèmes embarqués, ils en riront. À des fins courantes dans la programmation d'un microcontrôleur, la lecture de 4 bits bas de n'importe quel convertisseur analogique-numérique 16 bits avec une broche flottante (non connectée) produira un bruit aléatoire parfaitement bon, à une bande passante plus que suffisante (plus la période d'interrogation est courte, plus " bruyant "la lecture), et plus facile que d'écrire la routine RNG réelle. Et compte tenu du fait que les ADC se trouvent généralement implémentés dans le silicium des microcontrôleurs, généralement implémentés et souvent implémentés avec 8 canaux dont vous avez peut-être besoin de 5 pour votre application, c'est pratiquement gratuit.

Et même si vous n'avez pas d'ADC, quelques éléments connectés à une broche GPIO numérique produiront un très bon bruit. En embarqué, le bruit est omniprésent (et constamment combattu), et il est donc très facile d'obtenir un véritable caractère aléatoire.

4
SF.

Il existe de nombreuses façons d'essayer d'émuler une séquence de nombres "aléatoire". Votre premier arrêt devrait être de lire générateurs linéaires congruents , c'est sûr. C'est ainsi que fonctionnent la plupart des générateurs de nombres aléatoires de base, et je parie que c'est ainsi que fonctionne la fonction Rand () de PHP.

La question suivante la plus intéressante à méditer est la suivante: comment se produit-elle? temps? Adresse IP? etc.

2
Sean Owen

Tout d'abord, pratiquement toutes les fonctions Rand() ne fournissent pas le vrai caractère aléatoire, elles fournissent plutôt des nombres dits pseudo-aléatoires.

Alors, comment fonctionnent les générateurs de nombres pseudo-aléatoires? Fondamentalement, de la même manière que le cryptage fonctionne: vous avez une fonction (un hachage) qui prend une entrée et produit une sortie d'une manière si complexe qu'il est impossible à la sortie de deviner l'entrée ou vice versa. Autrement dit, chaque chiffre peut être utilisé pour créer un assez bon générateur pseudo-aléatoire. Cependant, bien que vous puissiez utiliser n'importe quel générateur pseudo-aléatoire pour effectuer le chiffrement en principe, la plupart des générateurs de nombres pseudo-aléatoires sont principalement développés pour la vitesse, et non pour la sécurité cryptographique, de sorte qu'ils ne donneront aucun mal de tête aux pirates.

Pour un générateur pseudo-aléatoire, la fonction de hachage est appliquée à un état interne caché du générateur, et sa sortie est utilisée pour a) modifier cet état interne et b) pour calculer la sortie de la Rand() une fonction. La prochaine invocation de Rand() utilisera cet état interne modifié et produira donc un résultat différent. Plus la fonction de hachage est bonne, moins les résultats sont faciles à distinguer des vrais nombres aléatoires.


En fait, les ordinateurs ont aujourd'hui accès à de vrais nombres aléatoires: ils proviennent de la gigue dans le timing des interruptions produites par les appareils externes. Linux utilise ces valeurs de petite incertitude pour remuer constamment un "pool d'entropie", qui n'est que de quelques kilo-octets d'état interne. Les hachages cryptographiques basés sur ce pool d'entropie sont disponibles via le /dev/random et /dev/urandom dispositifs. Ainsi, l'accès à de très bons nombres aléatoires est aussi simple que d'ouvrir l'un de ces deux appareils et d'en lire quelques octets.