Comment fonctionne le générateur aléatoire Java?


J'ai écrit un programme qui simule le jet de dés

    Random r = new Random();
    int result = r.nextInt(6);
    System.out.println(result);

Je veux savoir s'il existe un moyen de "prédire" le prochain numéro généré et comment la JVM détermine quel numéro générer ensuite?

Mon code produira-t-il des nombres proches du réel aléatoire sur n'importe quelle JVM et OS?

Author: David Mumladze, 2016-02-17

4 answers

Ce sont des nombres pseudo-aléatoires, ce qui signifie qu'à des fins générales, ils sont assez aléatoires. Cependant, ils sont déterministes et entièrement dépendants de la graine. Le code suivant imprimera les mêmes 10 numéros deux fois.

Random rnd = new Random(1234);
for(int i = 0;i < 10; i++)
    System.out.println(rnd.nextInt(100));

rnd = new Random(1234);
for(int i = 0;i < 10; i++)
    System.out.println(rnd.nextInt(100));

Si vous pouvez choisir la graine, vous pouvez d'abord précalculer les nombres, puis réinitialiser le générateur avec la même graine et vous saurez à l'avance quels nombres sortent.

 14
Author: Kayaman, 2016-02-17 12:12:25

Je veux savoir s'il existe un moyen de "prédire" le prochain numéro généré et comment la JVM détermine quel numéro générer ensuite?

Absolument. La classe Random est implémentée en tant que générateur de nombres congruentiels linéaires (LCNG). La formule générale pour un générateur congruentiel linéaire est:

new_state = (old_state * C1 + C2) modulo N

Précis de L'algorithme utilisé par Random est spécifié dans le javadocs. Si vous connaissez l'état actuel du générateur, l'état suivant est complètement prévisible.

Mon code produira-t-il des nombres proches du réel aléatoire sur n'importe quelle JVM et OS?

Si vous utilisez Random, alors Non. Pas pour n'importe quelle JVM sur n'importe quel système d'exploitation.

La séquence produite par un LCNG n'est certainement pas aléatoire, et a des propriétés statistiques qui sont significativement différentes d'une vraie séquence aléatoire. (La séquence sera fortement auto-corrélée, et cela apparaîtra si vous tracez les résultats des appels successifs à Random.nextInt().)

Est-ce un problème? Bien cela dépend des besoins de votre application. Si vous avez besoin de nombres" aléatoires " difficiles à prédire (par exemple pour un algorithme lié à la sécurité), alors clairement non. Et si les nombres vont être utilisés pour une simulation de Monte Carlo, alors l'auto-corrélation inate d'un LCNG peut fausser la simulation. Mais si vous venez de construire un jeu de cartes solitaire ... peut-être n'a pas d'importance.

 9
Author: Stephen C, 2016-02-17 13:06:40

Oui, il est possible de prédire quel nombre un générateur de nombres aléatoires produira ensuite. J'ai vu cela s'appeler craquer, casser ou attaquer le RNG. La recherche de l'un de ces termes avec "générateur de nombres aléatoires" devrait donner beaucoup de résultats.

LisezComment nous avons appris à tricher au Poker en ligne: Une étude sur la sécurité logicielle pour un excellent compte rendu de première main de la façon dont un générateur de nombres aléatoires peut être attaqué. Pour résumer, les auteurs ont compris ce qu'était RNG être utilisé sur la base d'un algorithme de brassage défectueux utilisé par un site de poker en ligne. Ils ont ensuite déterminé la graine de RNG en échantillonnant les mains qui ont été traitées. Une fois qu'ils avaient l'algorithme et la graine, ils savaient exactement comment le pont serait organisé après des brassages ultérieurs.

Vous pouvez également vous référer à ce lien .

 1
Author: Mohith P, 2016-02-17 11:50:52

Vérifiez Comment fonctionne java.util.Travail aléatoire et à quel point est-il bon?:

En d'autres termes, nous commençons par un nombre de départ ou de" graine " qui idéalement est "réellement imprévisible", et qui dans la pratique est "assez imprévisible". Par exemple, le nombre de millisecondes ou même nanosecondes-puisque l'ordinateur a été allumé est disponible sur la plupart des systèmes. Ensuite, chaque fois que nous voulons un nombre aléatoire, nous multiplions graine par un nombre fixe, un, ajouter un autre fixe nombre, c, ensuite, prenez le résultat modulo un autre nombre fixe, m. Le nombre a est généralement de grande taille. Cette méthode de génération de nombres aléatoires remonte à peu près à l'aube de computing1. À peu près tous les " occasionnels" générateur de nombres aléatoires auquel vous pouvez penser-de ceux de la science calculatrices aux ordinateurs personnels des années 1980 à currentday C et Visual Basic fonctions de bibliothèque-utilise une variante de la formule ci-dessus pour générer ses nombres aléatoires.

Et aussi Prédisant le à côté des Mathématiques.random () en Java

 1
Author: Rahul Tripathi, 2016-02-17 11:53:32