Il y avait en fait un très bon article que j'ai lu assez récemment sur les différents types de PRNG et comment ils se comportent en termes de plusieurs tests aléatoires différents. Malheureusement, je n'arrive pas à le trouver maintenant. L'essentiel de cela, cependant, était que les générateurs de nombres aléatoires par défaut dans presque tous les langages de programmation populaires sont assez naïfs et ont des biais assez importants.
Une autre réponse mentionne déjà qu'aucun PRNG, quel que soit le degré de sophistication de l'algorithme, n'est assez bon pour les applications cryptographiques. C'est vrai. Puisque vous mentionnez que cela sera utilisé pour "sélectionner un ticket gagnant", ignorons cela pour le moment.
L'algorithme Knuth utilisé par la classe .NET System.Random
est optimisé principalement pour la vitesse, pas pour la distribution aléatoire. Il est «assez aléatoire» pour de nombreuses raisons, dont la plupart des applications ne s'éloignent jamais trop, mais dans le domaine du jeu et de la simulation statistique, la plupart des gens semblent penser que c'est un mauvais choix. C'est mieux que les LCG qui étaient utilisés par défaut dans les bibliothèques plus anciennes, mais vous ne voulez toujours pas l'utiliser pour quelque chose comme un loto. Ne vous méprenez pas en pensant que vous utilisez simplement une source cryptographique, soit. Le problème avec les RNG cryptographiques est qu'ils remplissent un flux d'octets, mais le transformer en un seul entier aléatoire entre x et et exige que vous fassiez de l'arithmétique modulaire (ou arrondi - même résultat dans les deux cas). Et si votre gamme aléatoire ne se divise pas de façon parfaite en n'importe quelle puissance de 2 est définie par la longueur de l'octet, alors vous allez vous retrouver avec un biais dans les nombres inférieurs. Les données générées ont une entropie élevée, mais votre résultat sera biaisé. Par exemple, disons simplement que vous obtenez un nombre aléatoire "parfait" de 1 à 10 et que vous voulez le transformer en un nombre aléatoire compris entre 1 et 7. Comment le faites-vous? Calculer simplement result % 7
sera fortement biaisé vers les nombres 1-3. Il y a quelques façons de réduire le biais lors de l'utilisation d'un RNG crypto mais le point que j'essaie de faire est que les RNG cryptographiques sont conçus pour les applications cryptographiques, et l'utilisation d'un de ceux pour une simulation Monte Carlo n'est généralement pas la meilleure idée. Pour autant que je sache, le "bon" PRNG le plus populaire actuellement, qui est couramment utilisé dans les applications de jeu, est le Mersenne Twister. Il y a un .NET implementation here. Cet algorithme passe tous les Diehard Tests pour la distribution aléatoire; il ne montre presque aucun biais et est un bon choix lorsque vous utilisez des nombres aléatoires pour des applications probabilistes et statistiques. La bibliothèque scientifique GNU a également un numéro de RNG algorithms et, sans surprise, le Twister de Mersenne est en tête de liste.Cependant, certains des autres valent la peine d'être regardés par curiosité; RANLUX marque également assez haut sur l'essai irréductible IIRC.
Eric a raison avec son commentaire, bien sûr; toute cette information est pour rien si vous n'avez pas d'exigences techniques spécifiques sur "comment aléatoire" vous avez besoin de vos nombres aléatoires pour être. J'utilise une définition qui serait applicable à une application de jeu/de jeu à faible impact (c'est-à-dire pas un site majeur de jeu enregistré avec des millions de visiteurs par jour - il y a des règles plus strictes sur le hasard).
Définir clairement et précisément "aussi aléatoire que possible". Pour obtenir un signal réellement "aussi aléatoire que possible", vous avez besoin d'une source d'entropie - la graine - qui a plus de bits d'entropie que l'élément aléatoire généré à partir de cette graine. Donc, si vous avez déjà une variété de sources de données pour la graine, et qu'ils sont à forte entropie, alors vous avez déjà terminé. Il suffit d'extraire 24 bits de votre source d'entropie, ce qui vous donne un nombre entre 0 et 16 millions ** aussi aléatoire que possible compte tenu de votre source d'entropie **. –
En outre, il serait extrêmement utile si vous avez décrit ce que vous allez utiliser ce nombre aléatoire pour. –
Re: votre mise à jour: Maintenant, vous n'êtes plus dans le domaine des mathématiques et de la technologie, mais dans le domaine des réglementations légales. La plupart des gens qui lisent ce ne sont pas des avocats familiers avec les lois concernant les caractéristiques qu'un dispositif qui choisit le gagnant d'une loterie doit posséder. Je recommanderais de consulter un avocat et un statisticien avant de consacrer plus de temps à la recherche d'une solution technique. Il est certain qu'aucune solution "pseudo-aléatoire" * simple * ne sera acceptable; on peut facilement déterminer quel est le prochain numéro gagnant parmi les précédents avec un PRNG. –