Effectivement, je me suis bien vautré sur mon analyse précédente... oups.
En quoi un include à rajouter est-il problématique ? En quoi est-ce un problème même si on utilise openssl au final ?
OpenSSL répond à un autre problème : celui de disposer d'un générateur de nombres pseudo-aléatoire suffisamment fort pour être utilisable dans le domaine de la cryptographie. Quand bien même tu ais besoin d'un tel générateur pour un besoin précis, l'utiliser pour tous tes besoins est ce qu'on appelle communément une Erreur.
Pourquoi, me diras-tu ? (et là, je commence à simplifier, parce que le domaine est assez gros).
Pour la simple et bonne raison est qu'à part un support hardware complet (c'est à dire un générateur de nombre aléatoire hardware, ce qui pose d'autres problèmes) la seule manière d'avoir un générateur logiciel de nombre aléatoire non prédictible est d'utiliser un pool d'entropie qui est rempli par des événements non prévisibles (mouvements de la souris, espace de temps entre les frappes clavier...). Ces données sont en quantité finie : si le système ne reçoit pas d’événements pendant un temps donné, il est possible que le pool d'entropie soit vidé complètement. Dans ce cas, la récupération d'un nombré aléatoire devient impossible (il faut attendre que le pool d'entropie soit régénéré) et est implémenté généralement sous la forme d'un appel système bloquant.
Toute autre manière de faire se base sur des PRNG qui sont soit très complexes (et très lents) soit prédictibles (parce que le même seed donne la même séquence). Il existe des PRNG qui sont imprédictible lorsqu'on analyse une séquence courte produite (== après une séquence donnée, il est impossible de prédire la valeur suivante, même en connaissant l'algorithme), mais ces PRNG sont généralement coûteux en temps CPU. De plus, rallonger la séquence permet d'obtenir des informations supplémentaires qui peuvent permettre au final de deviner la suite (et donc les paramètres du PRNG, dont le seed ; à partir de là, tout est joué).
Autre manière de le dire : tous les utilisateurs de ce pool d'entropie dans le système sont arrêtés parce que tu as décidé de l'utiliser a des fins futiles.
C'est Mal. Si un programme consomme des ressources systèmes importantes alors qu'il n'en a pas besoin, c'est un bug. Il empêche d'autres programmes d'accéder à cette ressource, ce qui peut créer des problèmes en cascade (ex: "pourquoi est-ce que mon serveur web met 830 secondes à répondre à une requête HTTPS ?"). Il en faut pas le faire.
Dès lors que le besoin en PRNG (pseudo-random number generator) n''est pas un besoin avéré d'un CPRNG (cryptographic PRNG), alors il faut se contenter d'une algorithme soft qui sera de toute façon suffisant (en plus d'avoir d'autres caractéristiques intéressantes, comme la possibilité d'être rejoué une fois le seed connu).
(A noter que le standard C++ fournit aussi un device permettant de générer de vrais nombres aléatoires : random_device. Pas besoin d'OpenSSL pour ça).
On se ramène doucement à l'utilisation de <random>, qui propose des PRNG avec différentes caractéristiques (du générateur concurrentiel linéaire au mersenne twister). Son utilisation est simple, et (dès lors qu'on a pas besoin d'être au niveau crypto) suffisamment solide pour être utilisable dans tout type de projet. <random> propose même les outils permettant de généré des dés, ce qui est semblable à ton besoin (nombre entre 0 et 9).
Voilà. Si on veut rajouter un seed basé sur le temps, on peut procéder de la manière indiquée par Ehonn, ou tout simplement récupérer std::time(NULL).Code:
1
2
3
4
5
6
7
8
9
10
11 #include <random> std::default_random_engine my_generator; std::uniform_int_distribution<int> my_distribution(0,9); auto my_value_generator = std::bind ( my_distribution, my_generator ); int rand_n() { return my_value_generator(); }