Hasard est une bibliothèque de génération de nombres (pseudo) aléatoires.
Simplicité
Elle offre une API simple avec des fonctions de haut niveau et une distribution uniforme. Elle embarque de nombreux algorithmes (Mersenne Twister, ISAAC, RC4, etc.) et peut réutiliser des bibliothèques existantes (OpenSSL, GSL, GMP, glib).
Sécurité
Hasard choisit le meilleur générateur selon vos besoins et votre environnement (Linux, Windows, ...) en utilisant des « profils » (ex: « @fast » ou « @secure »). Le générateur est initialisée automatiquement en utilisant une entropie de bonne qualité (ex: /dev/urandom sous Linux). Les fonctions sont réentrantes et on peut utiliser des verrous pour les processus légers. La graine du générateur est regénérée lors d'un fork.
Tests
La bibliothèque inclut de nombreux tests (unitaires, régression, etc.) et également de nombreux outils pour stocker puis tester un générateur. Un format texte simple a été défini pour pouvoir stocker les nombres générés puis tester la qualité de ces nombres (mesure basique de l'entropie, génération d'images pour un contrôle visuel, etc.).
Hasard est distribué sous licence BSD, écrit en C et un binding Python est disponible. La version 0.8 fonctionne sous Linux, FreeBSD, Windows, sur i386 et x86_64. Voir le site du Projet Hasard pour les détails.
--
Générer des nombres aléatoires avec un ordinateur est un problème difficile, et à la moindre mégarde on peut introduire un biais dans la distribution (certains nombres seront plus fréquents que d'autres). Par exemple, « rand() % 10 » n'est pas la bonne méthode pour tirer un nombre entre 0 et 9, car elle est biaisée. Avec Hasard, hasard_int(rng, 0, 9) va garantir que chaque nombre tiré aura la même probabilité d'apparition.
De même, la graine des générateurs est souvent mal choisie et certaines séries de nombres seront alors plus fréquentes ou bien un attaquant pourra deviner les nombres qui vont être générés. Hasard utilise alors une source d'entropie fiable comme /dev/urandom (ou /dev/random pour le profil @secure).
De nombreux logiciels et bibliothèques ont connus des bugs dans leurs générateurs de nombres pseudo-aléatoires. Hasard n'est pas meilleur, mais possède de nombreux tests et est dédié à cette tâche. Exemples de bug :
* Python : randint() était toujours pair
* PHP : rand() et mt_rand() réinitialisent le générateur à chaque appel (le vrai problème étant que l'initialisation utilise une source d'entropie de mauvaise qualité)
* glibc : strfry() gives skewed distributions
* BIND9 : BIND 9 DNS Cache Poisoning (bugs dans les algorithmes LFSR implémentés)
* etc.
Lire le document doc/real_world.rst du projet Hasard pour d'autres exemples.
--
Journal précédent : Sortie de la bibliothèque Hasard version 0.2 (mai 2008)
# Et sinon il existe aussi...
Posté par Diagonale de Cantor (site web personnel) . Évalué à 10.
http://www.xkcd.com/221/
[^] # Re: Et sinon il existe aussi...
Posté par Pol' uX (site web personnel) . Évalué à 10.
http://dilbert.com/strips/comic/2001-10-25/
Adhérer à l'April, ça vous tente ?
[^] # Re: Et sinon il existe aussi...
Posté par Bozo_le_clown . Évalué à 8.
[^] # Re: Et sinon il existe aussi...
Posté par Pol' uX (site web personnel) . Évalué à 2.
Et qui initialisera l'initialiseur ?
Adhérer à l'April, ça vous tente ?
[^] # Re: Et sinon il existe aussi...
Posté par pasBill pasGates . Évalué à 6.
[^] # Re: Et sinon il existe aussi...
Posté par Larry Cow . Évalué à 3.
# Place d'Hasard par rapport à GSL, OpenSSL & cie
Posté par Victor STINNER (site web personnel) . Évalué à 10.
Comme Hasard 0.8 peut maintenant se « brancher » sur OpenSSL et gcrypt, une application qui a des besoins cryptographiques peut utiliser Hasard pour s'abstraire de la bibliothèque sous-jacente : utilisez OpenSSL ou gcrypt, selon vos envies ou vos contraintes (ex: licence).
Pour GSL par contre, je pense qu'il faudrait que ça soit l'inverse : GSL devrait réutiliser Hasard pour générer la graine des différents algorithmes, voir peut-être aussi pour gsl_rng_uniform_int() et gsl_rng_uniform(). Actuellement, GSL n'offre aucun moyen d'initialiser la graine d'un algorithme :-/
Hasard pourrait aussi être utilisé directement dans les applications ou dans un langage de programme. Il serait utile à pwgen par exemple (qui utilise /dev/urandom ou drand48 actuellement).
Les générateurs gmp_mt et glib d'Hasard me servent à tester Hasard et à tester les bibliothèques GMP et glib.
--
Comme l'indique son numéro de version (0.8 : 80%), Hasard n'est pas encore terminé et l'API risque encore de changer avant la version 1.0. Il est fort probable que l'API hasard_double() change car elle pose des problèmes pour l'intégration des autres bibliothèques.
[^] # Re: Place d'Hasard par rapport à GSL, OpenSSL & cie
Posté par Mouns (site web personnel) . Évalué à 1.
parce que cela me semble plutot interessant comme soft :)
faudrait aussi faire des binding python/perl/php & co ... yaka fokon ;)
[^] # Re: Place d'Hasard par rapport à GSL, OpenSSL & cie
Posté par Mouns (site web personnel) . Évalué à 2.
parce que cela me semble plutot interessant comme soft :)
faudrait aussi faire des binding python/perl/php & co ... yaka fokon ;)
[^] # Re: Place d'Hasard par rapport à GSL, OpenSSL & cie
Posté par Sytoka Modon (site web personnel) . Évalué à 2.
[^] # Re: Place d'Hasard par rapport à GSL, OpenSSL & cie
Posté par Victor STINNER (site web personnel) . Évalué à 2.
Je préfère attendre la prochaine version, voir la version 1.0. À vrai dire, j'aimerai qu'Hasard soit utilisé par une vraie application pour pouvoir peaufiner (et corriger) l'API avant de faire une grosse campagne de buzz :-)
faudrait aussi faire des binding python/perl/php & co ... yaka fokon ;)
Il y a déjà un binding Python. Je ne connais pas assez bien Perl et PHP pour écrire un binding pour ces langages. L'idéal serait qu'Hasard soit utilisé par Python, Perl, PHP & cie pour leur fonction "rand" :-)
[^] # Re: Place d'Hasard par rapport à GSL, OpenSSL & cie
Posté par Mouns (site web personnel) . Évalué à 3.
[^] # Re: Place d'Hasard par rapport à GSL, OpenSSL & cie
Posté par Mouns (site web personnel) . Évalué à 2.
[^] # Re: Place d'Hasard par rapport à GSL, OpenSSL & cie
Posté par Mouns (site web personnel) . Évalué à 2.
# .
Posté par snt . Évalué à 5.
>Par exemple, « rand() % 10 » n'est pas la bonne méthode pour tirer un nombre entre 0 et 9, car elle est biaisée.
Est-ce que tu as plus d'explications ou un lien quelconque ? Ça m'intéresse. Merci.
[^] # Re: .
Posté par PegaseYa . Évalué à 5.
voir les problèmes de bits de poids forts et faibles.
[^] # Re: .
Posté par 2PetitsVerres . Évalué à 10.
pour tout x € [0, 5], p(res = x) = 2/16
pour tout x € [6, 9], p(res = x) = 1/16
Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.
[^] # Re: .
Posté par psychoslave__ (site web personnel) . Évalué à 1.
Sinon merci pour ton explication.
[^] # Re: .
Posté par Bianca (site web personnel) . Évalué à 4.
Pour résumer, la méthode du modulo n'est pas biaisée si et seulement si (on se croirait en cours de maths au lycée tient) la sortie du générateur de nombre aléatoire % l'entier maximum que vous souhaitez obtenir + 1 = 0
Exemple :
Vous voulez un entier entre 0 et 31 et votre générateur de nombre aléatoire sort des nombre sur 6 bits non signé.
64 % (31+1) = 0 donc la technique du modulo peut s'appliquer.
Par contre si vous voulez un nombre entre 0 et 9, la technique du modulo ne fonctionne plus car 64 % (9+1) = 4
Question subsidiaire : Y'a-t-il une méthode non biaisée pour obtenir un chiffre entre 0 et 9 avec la sortie de la méthode rand()?
[^] # Re: .
Posté par fearan . Évalué à 3.
par contre il ne faut pas utiliser l'algorithme que je vais utiliser en cas de contrainte temps réels
l'idée de de relancer le générateur si il a trouvé une réponse dans la partie problématique.
pour reprendre l'exemple ci dessus si le générateur tire de 1 à 35 et qu'on veut un nombre allant de 1 à 10
rand1-10(){
while( a=rand1-35() > 30 );
return a%10+1;
}
Le truc c'est qu'avec l'aléatoire, on n'est jamais garanti de ne pas avoir une succession de cent fois un nombre entre 31et 35, ce qui donne un temps d'exécution aléatoire, mais toutes les durées ne sont pas équiprobable
(ie durée 1 => 30/35 => 6/7)
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: .
Posté par beagf (site web personnel) . Évalué à 4.
return (double)rand() / rand_max * borne_sup
a condition que borne_sup soit suffisament inferrieur à rand_max, ce qui est général est le cas puisque typiquement rand_max est égale à , 2^31, 2^32 ou 2^64 et que borne_sup est souvent relativement petit.
[^] # Re: .
Posté par Victor STINNER (site web personnel) . Évalué à 3.
C'est justement pour éviter que chacun recode sa fonction randrange(a,b), un peu biaisée voir complètement fausse, que j'ai codé Hasard.
La fonction hasard_engine_ulong() a subi de nombreuses réécritures et corrections :
* Hasard 0.1 : utilisation des flottants mais avec un arrondi foireux, les bornes (min/max) étaient 2x moins fréquentes :-/
* Hasard 0.3 : correction pour les bornes
* Hasard 0.4 : support des générateurs dont l'intervalle de sortie est plus petit que celui demandé par l'utilisateur
* Hasard 0.5 : réécriture de l'algorithme, utilise GMP et uniquement des nombres entiers (pour supporter les CPU 64 bits)
* Hasard 0.6 : réécriture de l'algorithme, basé sur celui de GSL, pour se passer de GMP (pour limiter les dépendances)
Je pense que l'algorithme actuel est bon. Il reste juste à gérer un dernier cas : quand ULONG+1 n'est pas un multiple de l'intervalle de sortie du générateur (cas rare, arrive pour certains générateurs peu utilisés et déconseillés).
[^] # Re: .
Posté par smeuuh . Évalué à 4.
Je ne connais pas d'algorithmes qui combinent l'équiprobabilité de la méthode de relance et un temps d'éxécution déterministe (et raisonnable, sinon c'est trop facile), mais ça doit exister.
[^] # Re: .
Posté par benoar . Évalué à 2.
[^] # Re: .
Posté par beagf (site web personnel) . Évalué à 3.
Le problème c'est que la majoritée des fonctions rand sont des GCL...
Dans le cas d'un générateur correct qui te produit des vrais entiers 32bits, si ta borne sup est relativement basse, du style 0..100, la solution du modulo est même très bonne. Elle est téoriquement biasée mais en pratique le biai est inexistant.
Le problème c'est quand ta borne est plus grande ou quand tu ne la connais pas à l'avance, dans ce cas la ça deviens plus génant et il faut utiliser de meilleure solutions.
Ce qui est important c'est de clairement cerner ses besoin. Le méthode avec rejet peuvent être andicapantes en pratique sans apporter vraiment plus de surtée.
[^] # Re: .
Posté par windu.2b . Évalué à 3.
Merci
[^] # Re: .
Posté par Dr BG . Évalué à 2.
[^] # Re: .
Posté par Antoine . Évalué à 10.
- Si le nombre tiré est entre 0 à 5, tu obtiens un nombre entre 0 et 5
- Si le nombre tiré est entre 6 et 9, tu obtiens un nombres entre 6 et 9
- Si le nombre tiré est entre 10 et 15, tu obtiens à nouveau un nombre entre 0 et 5.
Au final, tu as deux fois plus de chances d'obtenir un nombre entre 0 et 5 en utilisant le modulo.
[^] # Re: .
Posté par windu.2b . Évalué à 2.
Oki, je m'en vais, plein de honte, me flageller avec des orties fraîches !
[^] # Ne pas utiliser modulo
Posté par Victor STINNER (site web personnel) . Évalué à 2.
J'ai écrit ce document qui présente les erreurs courantes :
http://haypo.hachoir.org/hasard?file/tip/doc/common_errors.r(...)
Disons que l'intervalle de sortie du générateur soit [a; b] et celui que veut l'utilisateur est [x; y]. On peut utiliser le modulo à condition que :
* [a; b] soit plus grand (ou de même taille) que [x; y] : (b-a+1) >= (y-x+1)
* (b-a+1) soit multiple de (y-x+1)
Exemple : générateur : [0; 99] (100 nombres), utilisateur : [0; 9]. Si le générateur est uniforme, rand() % 10 sera aussi uniforme.
--
Hasard réutilise l'idée de l'algorithme de GSL, mais tire plusieurs nombres si l'intervalle du générateur est plus petit que celui de l'utilisateur. L'algorithme général est :
1. tirer un nombre au hasard
2. diviser ce nombre par un facteur (pour limiter le nombre d'itérations)
3. si le nombre est plus grand que ce que veut l'utilisateur, recommencer (retour en 1.)
Voir lib/randint.c pour les détails :
http://haypo.hachoir.org/hasard?file/tip/lib/randint.c
--
Autre document utile : présentations des implémentations de PRNG existantes, avec quelques bugs que j'ai noté :
http://haypo.hachoir.org/hasard?file/tip/doc/real_world.rst
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.