Générer des valeurs aléatoires par lancer de dés en C++

Jay Shaw 12 octobre 2023
  1. Générer des nombres aléatoires par lancer de dés en C++
  2. Générer des valeurs aléatoires similaires à un lancer de dés à l’aide de C++
  3. Conclusion
Générer des valeurs aléatoires par lancer de dés en C++

Les ordinateurs ne peuvent pas deviner les nombres. Chaque fois qu’une machine génère un nombre aléatoire, il s’agit soit d’un produit d’une opération au niveau du bit, soit d’un dérivé d’un facteur numérique, c’est-à-dire du temps, de séquences.

Le problème avec l’utilisation des méthodes ci-dessus est qu’elles produiront le même ensemble de résultats si elles sont répétées suffisamment de fois.

C’est pourquoi les algorithmes classiques utilisés pour générer des nombres aléatoires ne sont pas recommandés pour les pratiques cryptographiques. Les résultats sont faciles à prévoir.

Pour prédire le caractère aléatoire, lancer des dés est une tâche assez simple. Dans cet article, le lecteur découvrira le caractère aléatoire des ordinateurs et comment des résultats aléatoires peuvent être récupérés à partir d’un simple lancer de dés en utilisant C++.

Générer des nombres aléatoires par lancer de dés en C++

Un générateur pseudo-aléatoire est une machine qui crée des nombres qui semblent aléatoires. À l’inverse, ils sont entièrement prévisibles.

En effet, les générateurs de nombres aléatoires traditionnels utilisent une graine. Une graine, en termes simples, est une fonction injective qui dépend d’un temps ou d’une composante numérique.

Par exemple, les résultats produits pour une graine donnée x(0) en appliquant de manière répétée une fonction injective sur x(0), appelée f(x0), de sorte que fn(x0) diffère de fn-1(x0) ou fn+1(x0), où fn représente la structure de la fonction n fois.

En d’autres termes, f(x) contient de grands sauts qui sont pratiquement sans rapport avec les précédents.

Graine utilisant le temps pour créer un nombre aléatoire pour le lancer de dés en C++

Dans la plupart des cas, les graines générées dépendent du facteur temps. Cela signifie que la fonction injective factorise la seconde actuelle dans l’horloge.

Prenons un exemple pour mieux le comprendre.

unsigned main_seed;

main_seed = time(0);

srand(main_seed);

Ici, une variable non signée main_seed est initialisée ; cette variable est utilisée pour stocker l’heure actuelle. srand() est une fonction C++ qui génère un résultat à partir de la graine.

Une fois la graine générée, la fonction rand() peut être utilisée comme graine pour générer des valeurs aléatoires à l’aide d’une équation linéaire.

L’utilisation du facteur temps pour récupérer des graines distinctes peut sembler une bonne pratique à moins que des processeurs modernes ne soient impliqués car ils traitent des processus en nanosecondes, ce qui perturbe l’ensemble de la fonction en termes de caractère aléatoire.

Dans la plupart des cas, les graines générées dépendent du facteur temps. Cela signifie que la fonction injective factorise la seconde actuelle dans l’horloge.

Parce que l’horloge n’est pas aussi rapide qu’on pourrait le penser, si srand(time) est utilisé plusieurs fois en une seconde, la même graine est obtenue plusieurs fois. En conséquence, l’ensemble produit de nombres aléatoires sera similaire.

Et cela pourrait être un problème (important), en particulier dans les programmes de chiffrement par blocs. Dans ce dernier cas, les gens achètent un nombre décent de générateurs construits sur des adjectifs physiques en temps réel tels que la variance de température dans les données atmosphériques, etc., ou, dernièrement, sur la mesure de bits quantiques, par exemple sur le facteur de superposition des photons polarisés. .

Graine utilisant des nombres arbitraires pour créer un nombre aléatoire pour le lancer de dés en C++

L’exemple ci-dessous illustre un générateur de pseudo-numéros utilisant des nombres.

static unsigned long int rand_num = 2;

int rand(void)  // The ceiling limit is kept at 32767
{
  rand_num = rand_num * 113546545 + 12345;
  return (unsigned int)(rand_num / 65536) % 32768;
}

void srand(unsigned int main_seed)  // seed is stored inside variable main_seed
{
  rand_num = main_seed;
}

Une variable int non signée rand_num est initialisée avec la valeur 2. Il existe deux méthodes dans le programme ci-dessus - rand et srand.

La méthode rand concatène un nouveau nombre à la valeur initialisée. Lorsque la limite plafond pour la graine est définie, le mod de rand et la limite plafond renverront un nombre inférieur à la limite plafond.

Le résultat final renvoyé par cette méthode est converti en un entier non signé.

La méthode srand() passe la valeur de rand_num à la variable de départ main_seed.

Inconvénients de l’utilisation des méthodes ci-dessus

Comme on peut le voir, exécuter srand(time(0)) ou prendre des valeurs arbitraires pour la graine renvoie toujours de nouveaux nombres sur rand(), qui dépendent de la graine. Mais après quelques millions, les chiffres se répètent.

La graine contrôle quels nombres aléatoires sont créés dans l’ordre, c’est-à-dire que srand(1) produira presque toujours la même valeur lors du premier appel à rand(), le même nombre lors du deuxième appel à rand() , etc.

En d’autres termes, la sortie est toujours le même nombre aléatoire si la même graine est réensemencée avant chaque appel rand(). Ainsi, en semant plusieurs fois avec time(0) en une seule seconde, tous les nombres aléatoires seront les mêmes après le réensemencement.

Il doit se répéter après quelques cycles, mais l’argument srand définit le motif. Le rand C++ ne convient pas au chiffrement, car connaître la graine aide un pirate à estimer le nombre suivant.

Générer des valeurs aléatoires similaires à un lancer de dés à l’aide de C++

Ce programme utilise une graine générée par le temps pour produire des nombres aléatoires dans la plage de 1 à 6.

Importer des packages

Trois packages d’importation sont nécessaires dans ce programme :

  1. iostream
  2. cstdlib - pour la fonction temporelle et les opérations en rand
  3. time - package d’en-tête pour les fonctions temporelles

iostream est importé pour les opérations d’entrée-sortie dans le programme. L’autre package, cstdlib, est utilisé pour les opérations de contrôle de base dans les programmes C++.

Le troisième package est le package time qui sera utilisé pour créer la graine du programme.

Générer des valeurs selon le Die Roll In C++

Un dé a 6 valeurs individuelles. Le rôle du programme doit être de générer un nombre naturel aléatoire à l’intérieur de la plage, qui peut se répéter dans les lancers de dé ultérieurs, mais le résultat global doit sembler purement aléatoire.

Trois variables sont initialisées pour trouver le résultat. Les variables floor et ceiling stockent les valeurs les plus basses et les plus hautes du dé, et la variable outcome est utilisée pour trouver le nombre aléatoire.

int outcome;
int l_limit = 1;
int h_limit = 6;

La valeur finale est générée à l’aide de la fonction rand(), limitant le résultat à l’intérieur de la plage supérieure et inférieure.

outcome = rand() % (max - min + 1) + min;

Enfin, la variable roll est renvoyée.

int outcome;
int l_limit = 1;  // floor or lower limit of a die
int h_limit = 6;  // ceiling or higher limit of a die

outcome = rand() % (h_limit - l_limit + 1) + l_limit;

return outcome;

Générer une graine en utilisant le temps et afficher les résultats

Le programme prend l’heure actuelle dans la fonction srand() et la passe à la fonction rand(). L’application utilise la fonction rand() de la méthode Droll() pour trouver des nombres naturels à l’intérieur des limites stipulées.

srand(time(0));

Une fois la graine produite, la méthode Droll() doit être appelée et le résultat doit être imprimé.

Classiquement, trois jets de dé sont toujours considérés comme un jeu complet. Cette technique est répétée trois fois pour vérifier le caractère aléatoire.

Nous devrons placer la méthode Droll() dans une boucle for et appeler trois fois à l’intérieur de l’instruction print. Le résultat final est une matrice 3X3 de nombres pseudo-aléatoires générés à partir d’un lancer de dé.

for (int i = 0; i < 3; i++) {
  std::cout << Droll() << " ";
  std::cout << Droll() << " ";
  std::cout << Droll() << std::endl;
}

Mettons tout ensemble dans le programme et visualisons les résultats.

#include <cstdlib>
#include <iostream>

#include "time.h"

int Droll() {
  int outcome;
  int l_limit = 1;  // floor or lower limit of a die
  int h_limit = 6;  // ceiling or higher limit of a die

  outcome = rand() % (h_limit - l_limit + 1) + l_limit;

  return outcome;
}

int main() {
  srand(time(0));
  for (int i = 0; i < 3; i++) {
    std::cout << Droll() << " ";
    std::cout << Droll() << " ";
    std::cout << Droll() << std::endl;
  }
}

Production:

3 1 2
6 1 3
4 5 4

--------------------------------
Process exited after 0.00784 seconds with return value 0
Press any key to continue . . .

Conclusion

Cet article explique les bases des générateurs de pseudo nombres. Les lecteurs ont vu les différentes méthodes pour générer un nombre aléatoire et leurs avantages et inconvénients.

Un programme C++ est fourni pour clarifier les concepts sur la façon dont les nombres aléatoires sont générés à l’intérieur de la plage et sur la façon dont un lancer de dés peut être imité à l’aide d’un programme informatique.

Article connexe - C++ Random