Existe-t-il une fonction pour générer un nombre entier aléatoire dans C? Ou devrai-je utiliser une bibliothèque tierce?
srand
: pourquoi l'appeler une seule fois .
Existe-t-il une fonction pour générer un nombre entier aléatoire dans C? Ou devrai-je utiliser une bibliothèque tierce?
srand
: pourquoi l'appeler une seule fois .
Réponses:
Remarque : ne pas utiliser
rand()
pour la sécurité. Si vous avez besoin d'un numéro cryptographiquement sécurisé, consultez plutôt cette réponse .
#include <time.h>
#include <stdlib.h>
srand(time(NULL)); // Initialization, should only be called once.
int r = rand(); // Returns a pseudo-random integer between 0 and RAND_MAX.
Edit : Sous Linux, vous préférerez peut-être utiliser aléatoire et aléatoire .
time()
ne change qu'une fois par seconde. Si vous amorcez time()
, pour chaque appel vers rand()
, vous obtiendrez la même valeur pour chaque appel pendant une seule seconde. Mais la raison principale est que les propriétés rand()
et les fonctions de ce type sont mieux connues pour le cas d'utilisation où elles sont introduites exactement une fois par exécution, et non à chaque appel. Dépendre du "caractère aléatoire" avec des propriétés non testées ou non prouvées conduit à des problèmes.
rand()
généralement le cas) avec l'ensemencement rand()
n'aurait au mieux aucun effet, et au pire romprait les qualités connues du générateur. C'est un sujet profond. Commencez par lire Knuth Vol 2 Chapitre 3 sur les nombres aléatoires comme la meilleure introduction aux mathématiques et aux pièges.
srand((unsigned int)time(NULL));
La rand()
fonction dans <stdlib.h>
renvoie un entier pseudo-aléatoire entre 0 et RAND_MAX
. Vous pouvez utiliser srand(unsigned int seed)
pour définir une graine.
Il est courant d'utiliser l' %
opérateur en conjonction avec rand()
pour obtenir une plage différente (mais gardez à l'esprit que cela annule quelque peu l'uniformité). Par exemple:
/* random int between 0 and 19 */
int r = rand() % 20;
Si vous vous souciez vraiment de l'uniformité, vous pouvez faire quelque chose comme ceci:
/* Returns an integer in the range [0, n).
*
* Uses rand(), and so is affected-by/affects the same seed.
*/
int randint(int n) {
if ((n - 1) == RAND_MAX) {
return rand();
} else {
// Supporting larger values for n would requires an even more
// elaborate implementation that combines multiple calls to rand()
assert (n <= RAND_MAX)
// Chop off all of the values that would cause skew...
int end = RAND_MAX / n; // truncate skew
assert (end > 0);
end *= n;
// ... and ignore results from rand() that fall above that limit.
// (Worst case the loop condition should succeed 50% of the time,
// so we can expect to bail out of this loop pretty quickly.)
int r;
while ((r = rand()) >= end);
return r % n;
}
}
%
est l'opérateur de module. Il vous donne le reste d'une division entière, x % n
vous donnera donc toujours un nombre compris entre0
et n - 1
(tant que x
et n
sont tous deux positifs). Si vous trouvez toujours cela déroutant, essayez d'écrire un programme qui i
compte de 0 à 100 et imprime i % n
pour certains n
de votre choix moins de 100.
Comme indiqué dans la façon de générer en toute sécurité des nombres aléatoires dans divers langages de programmation , vous souhaiterez effectuer l'une des opérations suivantes:
randombytes
/dev/urandom
, non /dev/random
. Pas OpenSSL (ou d'autres PRNG d'espace utilisateur).Par exemple:
#include "sodium.h"
int foo()
{
char myString[32];
uint32_t myInt;
if (sodium_init() < 0) {
/* panic! the library couldn't be initialized, it is not safe to use */
return 1;
}
/* myString will be an array of 32 random bytes, not null-terminated */
randombytes_buf(myString, 32);
/* myInt will be a random number between 0 and 9 */
myInt = randombytes_uniform(10);
}
randombytes_uniform()
est cryptographiquement sécurisé et impartial.
sodium_init()
à un moment donné. Ne vous inquiétez pas pour le RNG, il utilise celui du noyau.
sodium_init()
même si elle ne fait pas nécessairement partie de mon exemple car c'est un détail important.
Passons par là. Nous utilisons d'abord la fonction srand () pour amorcer le randomiseur. Fondamentalement, l'ordinateur peut générer des nombres aléatoires en fonction du nombre fourni à srand (). Si vous donniez la même valeur de départ, les mêmes nombres aléatoires seraient générés à chaque fois.
Par conséquent, nous devons semer le randomiseur avec une valeur qui change toujours. Nous le faisons en lui fournissant la valeur de l'heure actuelle avec la fonction time ().
Maintenant, lorsque nous appelons rand (), un nouveau nombre aléatoire sera produit à chaque fois.
#include <stdio.h>
int random_number(int min_num, int max_num);
int main(void)
{
printf("Min : 1 Max : 40 %d\n", random_number(1,40));
printf("Min : 100 Max : 1000 %d\n",random_number(100,1000));
return 0;
}
int random_number(int min_num, int max_num)
{
int result = 0, low_num = 0, hi_num = 0;
if (min_num < max_num)
{
low_num = min_num;
hi_num = max_num + 1; // include max_num in output
} else {
low_num = max_num + 1; // include max_num in output
hi_num = min_num;
}
srand(time(NULL));
result = (rand() % (hi_num - low_num)) + low_num;
return result;
}
else{ low_num=max_num; hi_num=min_num+1;
2) échoue quand hi_num - low_num > INT_MAX
. 3) Omet des valeurs dans la situation rare INT_MAX > hi_num - low_num > RAND_MAX
.
hi_num = max_num + 1;
manque de protection contre le débordement.
Si vous avez besoin de nombres pseudo aléatoires de meilleure qualité que ceux stdlib
fournis, consultez Mersenne Twister . C'est aussi plus rapide. Les exemples d'implémentations sont nombreux, par exemple ici .
La fonction C standard est rand()
. C'est assez bon pour distribuer des cartes pour le solitaire, mais c'est horrible. De nombreuses implémentations font rand()
défiler une courte liste de nombres, et les bits bas ont des cycles plus courts. La façon dont certains programmes appellent rand()
est horrible, et calculer une bonne graine à passer srand()
est difficile.
La meilleure façon de générer des nombres aléatoires en C est d'utiliser une bibliothèque tierce comme OpenSSL. Par exemple,
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/rand.h>
/* Random integer in [0, limit) */
unsigned int random_uint(unsigned int limit) {
union {
unsigned int i;
unsigned char c[sizeof(unsigned int)];
} u;
do {
if (!RAND_bytes(u.c, sizeof(u.c))) {
fprintf(stderr, "Can't get random bytes!\n");
exit(1);
}
} while (u.i < (-limit % limit)); /* u.i < (2**size % limit) */
return u.i % limit;
}
/* Random double in [0.0, 1.0) */
double random_double() {
union {
uint64_t i;
unsigned char c[sizeof(uint64_t)];
} u;
if (!RAND_bytes(u.c, sizeof(u.c))) {
fprintf(stderr, "Can't get random bytes!\n");
exit(1);
}
/* 53 bits / 2**53 */
return (u.i >> 11) * (1.0/9007199254740992.0);
}
int main() {
printf("Dice: %d\n", (int)(random_uint(6) + 1));
printf("Double: %f\n", random_double());
return 0;
}
Pourquoi autant de code? D'autres langages comme Java et Ruby ont des fonctions pour les nombres entiers ou flottants aléatoires. OpenSSL ne donne que des octets aléatoires, donc j'essaie d'imiter comment Java ou Ruby les transformerait en nombres entiers ou flottants.
Pour les entiers, nous voulons éviter le biais modulo . Supposons que nous ayons obtenu des nombres entiers aléatoires à 4 chiffres rand() % 10000
, mais rand()
ne pouvons renvoyer que 0 à 32767 (comme c'est le cas dans Microsoft Windows). Chaque nombre de 0 à 2767 apparaîtra plus souvent que chaque nombre de 2768 à 9999. Pour supprimer le biais, nous pouvons réessayer rand()
alors que la valeur est inférieure à 2768, car les 30000 valeurs de 2768 à 32767 correspondent uniformément aux 10000 valeurs de 0 à 9999.
Pour les flottants, nous voulons 53 bits aléatoires, car a double
contient 53 bits de précision (en supposant que c'est un double IEEE). Si nous utilisons plus de 53 bits, nous obtenons un biais d'arrondi. Certains programmeurs écrivent du code comme rand() / (double)RAND_MAX
, mais rand()
peuvent renvoyer seulement 31 bits, ou seulement 15 bits sous Windows.
Les RAND_bytes()
graines d'OpenSSL lui-même, peut-être en lisant /dev/urandom
sous Linux. Si nous avons besoin de nombreux nombres aléatoires, il serait trop lent de les lire tous /dev/urandom
, car ils doivent être copiés à partir du noyau. Il est plus rapide de permettre à OpenSSL de générer plus de nombres aléatoires à partir d'une graine.
En savoir plus sur les nombres aléatoires:
srand()
. Il mélange les bits de l'heure actuelle, l'ID du processus et certains pointeurs, s'il ne peut pas lire /dev/urandom
.float
/ double
, j'ai donc clarifié la question pour vous en tenir aux int
chiffres pour éviter de la rendre trop large. Il y a d'autres questions C traitant spécifiquement des valeurs float
/ double
aléatoires, vous pouvez donc vouloir republier votre deuxième moitié de votre réponse à des questions telles que stackoverflow.com/questions/13408990/…
Si votre système prend en charge la arc4random
famille de fonctions, je recommanderais de les utiliser à la place de la rand
fonction standard .
La arc4random
famille comprend:
uint32_t arc4random(void)
void arc4random_buf(void *buf, size_t bytes)
uint32_t arc4random_uniform(uint32_t limit)
void arc4random_stir(void)
void arc4random_addrandom(unsigned char *dat, int datlen)
arc4random
renvoie un entier non signé de 32 bits aléatoire.
arc4random_buf
met du contenu aléatoire dans son paramètre buf : void *
. La quantité de contenu est déterminée par le bytes : size_t
paramètre.
arc4random_uniform
renvoie un entier non signé aléatoire de 32 bits qui suit la règle:, 0 <= arc4random_uniform(limit) < limit
où limite est également un entier non signé de 32 bits.
arc4random_stir
lit /dev/urandom
et transmet les données à arc4random_addrandom
pour randomiser en plus son pool de nombres aléatoires internes.
arc4random_addrandom
est utilisé par arc4random_stir
pour remplir son pool de nombres aléatoires internes en fonction des données qui lui sont transmises.
Si vous ne disposez pas de ces fonctions, mais que vous êtes sous Unix, vous pouvez utiliser ce code:
/* This is C, not C++ */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h> /* exit */
#include <stdio.h> /* printf */
int urandom_fd = -2;
void urandom_init() {
urandom_fd = open("/dev/urandom", O_RDONLY);
if (urandom_fd == -1) {
int errsv = urandom_fd;
printf("Error opening [/dev/urandom]: %i\n", errsv);
exit(1);
}
}
unsigned long urandom() {
unsigned long buf_impl;
unsigned long *buf = &buf_impl;
if (urandom_fd == -2) {
urandom_init();
}
/* Read 4 bytes, or 32 bits into *buf, which points to buf_impl */
read(urandom_fd, buf, sizeof(long));
return buf_impl;
}
La urandom_init
fonction ouvre l' /dev/urandom
appareil et place le descripteur de fichier urandom_fd
.
La urandom
fonction est fondamentalement la même qu'un appel à rand
, sauf plus sécurisée, et elle renvoie un long
(facilement modifiable).
Cependant, cela /dev/urandom
peut être un peu lent, il est donc recommandé de l'utiliser comme source pour un générateur de nombres aléatoires différent.
Si votre système ne possède pas de fichier /dev/urandom
, mais possède un /dev/random
fichier similaire, vous pouvez simplement modifier le chemin d'accès passé à open
in urandom_init
. Les appels et les API utilisés dans urandom_init
et urandom
sont (je crois) compatibles POSIX, et en tant que tels, devraient fonctionner sur la plupart, sinon sur tous les systèmes compatibles POSIX.
Remarques: Une lecture depuis /dev/urandom
ne bloquera PAS s'il n'y a pas suffisamment d'entropie disponible, donc les valeurs générées dans de telles circonstances peuvent être cryptographiquement non sécurisées. Si cela vous inquiète, utilisez alors /dev/random
, qui bloquera toujours si l'entropie est insuffisante.
Si vous êtes sur un autre système (c'est-à-dire Windows), utilisez rand
ou une API non portable spécifique à la plate-forme spécifique à Windows.
Wrapper fonction pour urandom
, rand
ou des arc4random
appels:
#define RAND_IMPL /* urandom(see large code block) | rand | arc4random */
int myRandom(int bottom, int top){
return (RAND_IMPL() % (top - bottom)) + bottom;
}
STL n'existe pas pour C. Vous devez appeler rand
, ou mieux encore, random
. Ceux-ci sont déclarés dans l'en-tête de bibliothèque standard stdlib.h
. rand
est POSIX, random
est une fonction de spécification BSD.
La différence entre rand
et random
est qu'elle random
renvoie un nombre aléatoire 32 bits beaucoup plus utilisable et rand
renvoie généralement un nombre 16 bits. Les pages de manuel BSD montrent que les bits inférieurs de rand
sont cycliques et prévisibles, donc rand
potentiellement inutiles pour les petits nombres.
extern int rand(void);
et extern void srand(unsigned int);
.
Jetez un œil à ISAAC (Indirection, Shift, Accumulate, Add et Count). Son uniformément distribué et a une longueur moyenne de cycle de 2 ^ 8295.
C'est un bon moyen d'obtenir un nombre aléatoire entre deux nombres de votre choix.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define randnum(min, max) \
((rand() % (int)(((max) + 1) - (min))) + (min))
int main()
{
srand(time(NULL));
printf("%d\n", randnum(1, 70));
}
Sortie la première fois: 39
Sortie la deuxième fois: 61
Sortie la troisième fois: 65
Vous pouvez changer les valeurs après randnum
en n'importe quel nombre que vous choisissez, et cela générera un nombre aléatoire pour vous entre ces deux nombres.
Vous voulez utiliser rand()
. Remarque ( TRÈS IMPORTANT ): assurez-vous de définir la valeur de départ pour la fonction rand. Sinon, vos nombres aléatoires ne sont pas vraiment aléatoires . C'est très, très, très important. Heureusement, vous pouvez généralement utiliser une combinaison de la minuterie du système et de la date pour obtenir une bonne graine.
FWIW, la réponse est que oui, il existe une stdlib.h
fonction appelée rand
; cette fonction est réglée principalement pour la vitesse et la distribution, pas pour l'imprévisibilité. Presque toutes les fonctions aléatoires intégrées pour divers langages et frameworks utilisent cette fonction par défaut. Il existe également des générateurs de nombres aléatoires "cryptographiques" qui sont beaucoup moins prévisibles, mais fonctionnent beaucoup plus lentement. Ceux-ci doivent être utilisés dans toute sorte d'application liée à la sécurité.
Nous espérons que c'est un peu plus aléatoire que de simplement utiliser srand(time(NULL))
.
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
srand((unsigned int)**main + (unsigned int)&argc + (unsigned int)time(NULL));
srand(rand());
for (int i = 0; i < 10; i++)
printf("%d\n", rand());
}
Eh bien, STL est C ++, pas C, donc je ne sais pas ce que vous voulez. Si vous voulez C, cependant, il y a les fonctions rand()
et srand()
:
int rand(void);
void srand(unsigned seed);
Ils font tous deux partie de ANSI C. Il y a aussi la random()
fonction:
long random(void);
Mais pour autant que je sache, ce random()
n'est pas la norme ANSI C. Une bibliothèque tierce n'est peut-être pas une mauvaise idée, mais tout dépend de la façon dont un nombre aléatoire doit être généré.
C Programme pour générer un nombre aléatoire entre 9 et 50
#include <time.h>
#include <stdlib.h>
int main()
{
srand(time(NULL));
int lowerLimit = 10, upperLimit = 50;
int r = lowerLimit + rand() % (upperLimit - lowerLimit);
printf("%d", r);
}
En général, nous pouvons générer un nombre aléatoire entre lowerLimit et upperLimit-1
c'est-à-dire que lowerLimit est inclusif ou dites r ∈ [lowerLimit, upperLimit)
rand()
est le moyen le plus pratique pour générer des nombres aléatoires.
Vous pouvez également attraper un nombre aléatoire à partir de n'importe quel service en ligne comme random.org.
#include <stdio.h>
#include <stdlib.h>
void main()
{
int visited[100];
int randValue, a, b, vindex = 0;
randValue = (rand() % 100) + 1;
while (vindex < 100) {
for (b = 0; b < vindex; b++) {
if (visited[b] == randValue) {
randValue = (rand() % 100) + 1;
b = 0;
}
}
visited[vindex++] = randValue;
}
for (a = 0; a < 100; a++)
printf("%d ", visited[a]);
}
#include <stdio.h>
#include <dos.h>
int random(int range);
int main(void)
{
printf("%d", random(10));
return 0;
}
int random(int range)
{
struct time t;
int r;
gettime(&t);
r = t.ti_sec % range;
return r;
}
Sur les processeurs x86_64 modernes, vous pouvez utiliser le générateur de nombres aléatoires matériel via _rdrand64_step()
Exemple de code:
#include <immintrin.h>
uint64_t randVal;
if(!_rdrand64_step(&randVal)) {
// Report an error here: random number generation has failed!
}
// If no error occured, randVal contains a random 64-bit number
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//generate number in range [min,max)
int random(int min, int max){
int number = min + rand() % (max - min);
return number;
}
//Driver code
int main(){
srand(time(NULL));
for(int i = 1; i <= 10; i++){
printf("%d\t", random(10, 100));
}
return 0;
}
En entendant une bonne explication de pourquoi utiliser rand()
pour produire des nombres aléatoires uniformément distribués dans une plage donnée est une mauvaise idée, j'ai décidé de jeter un coup d'œil à la fausseté réelle de la sortie. Mon cas de test était un lancer de dés correct. Voici le code C:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
int i;
int dice[6];
for (i = 0; i < 6; i++)
dice[i] = 0;
srand(time(NULL));
const int TOTAL = 10000000;
for (i = 0; i < TOTAL; i++)
dice[(rand() % 6)] += 1;
double pers = 0.0, tpers = 0.0;
for (i = 0; i < 6; i++) {
pers = (dice[i] * 100.0) / TOTAL;
printf("\t%1d %5.2f%%\n", dice[i], pers);
tpers += pers;
}
printf("\ttotal: %6.2f%%\n", tpers);
}
et voici sa sortie:
$ gcc -o t3 t3.c
$ ./t3
1666598 16.67%
1668630 16.69%
1667682 16.68%
1666049 16.66%
1665948 16.66%
1665093 16.65%
total: 100.00%
$ ./t3
1667634 16.68%
1665914 16.66%
1665542 16.66%
1667828 16.68%
1663649 16.64%
1669433 16.69%
total: 100.00%
Je ne sais pas à quel point vous avez besoin que vos nombres aléatoires soient uniformes, mais ce qui précède semble suffisamment uniforme pour la plupart des besoins.
Edit: ce serait une bonne idée d'initialiser le PRNG avec quelque chose de mieux que time(NULL)
.
J'ai eu un sérieux problème avec le générateur de nombres pseudo aléatoires dans ma récente application: j'ai appelé à plusieurs reprises mon programme C via un script pyhton et j'utilisais comme graine le code suivant:
srand(time(NULL))
Cependant, puisque:
man srand
);time
elle renverra la même valeur à chaque fois.Mon programme a généré la même séquence de chiffres. Vous pouvez faire 3 choses pour résoudre ce problème:
mélanger la sortie de temps avec d'autres informations changeant lors des exécutions (dans mon application, le nom de la sortie):
srand(time(NULL) | getHashOfString(outputName))
J'ai utilisé djb2 comme fonction de hachage.
Augmentez la résolution temporelle. Sur ma plateforme, clock_gettime
était disponible, donc je l'utilise:
#include<time.h>
struct timespec nanos;
clock_gettime(CLOCK_MONOTONIC, &nanos)
srand(nanos.tv_nsec);
Utilisez les deux méthodes ensemble:
#include<time.h>
struct timespec nanos;
clock_gettime(CLOCK_MONOTONIC, &nanos)
srand(nanos.tv_nsec | getHashOfString(outputName));
L'option 3 vous assure (pour autant que je sache) la meilleure randomité des graines, mais elle peut créer une différence uniquement sur une application très rapide. À mon avis, l'option 2 est une valeur sûre.
rand()
ne doit pas être utilisé pour des données cryptographiques, je suis d'accord. Au moins pour moi, mon application n'impliquait pas de données cryptographiques, donc pour moi, c'était correct la méthode donnée.
Malgré toutes les suggestions des gens rand()
ici, vous ne voulez pas l'utiliser rand()
sauf si vous le devez! Les nombres aléatoires qui rand()
produisent sont souvent très mauvais. Pour citer la page de manuel Linux:
Les versions de
rand()
etsrand()
dans la bibliothèque Linux C utilisent le même générateur de nombres aléatoires querandom(3)
etsrandom(3)
, donc les bits de poids faible doivent être aussi aléatoires que les bits de poids fort. Cependant, sur les anciennes implémentations rand () et sur les implémentations actuelles sur différents systèmes, les bits d'ordre inférieur sont beaucoup moins aléatoires que les bits d'ordre supérieur . N'utilisez pas cette fonction dans des applications destinées à être portables lorsqu'un bon caractère aléatoire est nécessaire. ( Utilisez à larandom(3)
place. )
En ce qui concerne la portabilité, random()
est également défini par la norme POSIX depuis un certain temps maintenant. rand()
est plus ancien, il figurait déjà dans la première spécification POSIX.1 (IEEE Std 1003.1-1988), alors qu'il random()
est apparu pour la première fois dans POSIX.1-2001 (IEEE Std 1003.1-2001), mais le standard POSIX actuel est déjà POSIX.1-2008 (IEEE Std 1003.1-2008), qui a reçu une mise à jour il y a tout juste un an (IEEE Std 1003.1-2008, édition 2016). Je considère random()
donc que c'est très portable.
POSIX.1-2001 a également introduit les fonctions lrand48()
et mrand48()
, voir ici :
Cette famille de fonctions doit générer des nombres pseudo-aléatoires à l'aide d'un algorithme congruentiel linéaire et d'une arithmétique entière sur 48 bits.
Et la très bonne source pseudo aléatoire est la arc4random()
fonction disponible sur de nombreux systèmes. Ne fait partie d'aucune norme officielle, est apparu dans BSD vers 1997, mais vous pouvez le trouver sur des systèmes comme Linux et macOS / iOS.
random()
n'existe pas sous Windows.
rand()
car il est également requis par la norme C. Pour toute autre chose, vous avez besoin d'une solution spéciale pour Windows uniquement, comme d'habitude. #ifdef _WIN32
est la phrase que vous verrez le plus souvent dans le code multiplateforme qui veut prendre en charge Windows.En général, il existe une solution qui fonctionne avec tous les systèmes et une qui est requise pour Windows uniquement.
Pour les applications Linux C:
Il s'agit de mon code retravaillé à partir d'une réponse ci-dessus qui suit mes pratiques de code C et renvoie un tampon aléatoire de toute taille (avec des codes de retour appropriés, etc.). Assurez-vous d'appeler urandom_open()
une fois au début de votre programme.
int gUrandomFd = -1;
int urandom_open(void)
{
if (gUrandomFd == -1) {
gUrandomFd = open("/dev/urandom", O_RDONLY);
}
if (gUrandomFd == -1) {
fprintf(stderr, "Error opening /dev/urandom: errno [%d], strerrer [%s]\n",
errno, strerror(errno));
return -1;
} else {
return 0;
}
}
void urandom_close(void)
{
close(gUrandomFd);
gUrandomFd = -1;
}
//
// This link essentially validates the merits of /dev/urandom:
// http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
//
int getRandomBuffer(uint8_t *buf, int size)
{
int ret = 0; // Return value
if (gUrandomFd == -1) {
fprintf(stderr, "Urandom (/dev/urandom) file not open\n");
return -1;
}
ret = read(gUrandomFd, buf, size);
if (ret != size) {
fprintf(stderr, "Only read [%d] bytes, expected [%d]\n",
ret, size);
return -1;
} else {
return 0;
}
}
Ma solution minimaliste devrait fonctionner pour des nombres aléatoires dans la plage [min, max)
. Utilisez srand(time(NULL))
avant d'appeler la fonction.
int range_rand(int min_num, int max_num) {
if (min_num >= max_num) {
fprintf(stderr, "min_num is greater or equal than max_num!\n");
}
return min_num + (rand() % (max_num - min_num));
}
Essayez ceci, je l'ai rassemblé à partir de certains des concepts déjà référencés ci-dessus:
/*
Uses the srand() function to seed the random number generator based on time value,
then returns an integer in the range 1 to max. Call this with random(n) where n is an integer, and you get an integer as a return value.
*/
int random(int max) {
srand((unsigned) time(NULL));
return (rand() % max) + 1;
}
srand()
chaque fois que vous voulez appeler rand()
est une idée terrible. Étant donné time()
que renvoie généralement une valeur en secondes, l' appel rapide de cette fonction renvoie la même valeur "aléatoire".
random()
fonction d'Unix .