...
The C Standard function rand()
(available in stdlib.h
) does not have good random number properties. The numbers generated by rand()
have a comparatively short cycle, and the numbers may be predictable.
To achieve the best random numbers possible, an implementation-specific function must be used. When unpredictability really matters and speed is not an issue, such as in the creation of strong cryptographic keys, use a true entropy source such as /dev/random
or a hardware device capable of generating random numbers. The /dev/random
device may block for a long time if there are not enough events going on to generate sufficient entropy. From the Linux urandom(4)
manual page:
A read from the
/dev/urandom
device will not block waiting for more entropy. As a result, if there is not sufficient entropy in the entropy pool, the returned values are theoretically vulnerable to a cryptographic attack on the algorithms used by the driver. Knowledge of how to do this is not available in the current non-classified literature, but it is theoretically possible that such an attack may exist. If this is a concern in your application, use/dev/random
instead.
In many cases, however, it will be acceptable to simply use a pseudorandom number generator from a cryptographic library (such as the Mersenne Twister) and seed it with data read from /dev/random
.
Non-Compliant Code Example
...
Compliant Solution (POSIX)
This compliant solution improves the previous non-compliant code example by adding some additional sources of information to the seed.
Code Block | ||
---|---|---|
| ||
long int li; FILE* fd; if(!(fd = fopen("/dev/random", "r")) { /* Handle error condition */ } if(fread(&li, sizeof(li), 1, fd) != sizeof(li)) { /* Handle error condition */ } fclose(fd); printf("Random number: %ld\n", li);enum {len = 12}; char id[len]; /* id will hold the ID, starting with the characters "ID" */ /* followed by a random integer */ int r; int num; /* ... */ srandom(time(0)*getpid()); /* seed the PRNG with the current time */ /* ... */ r = random(); /* generate a random integer */ num = snprintf(id, len, "ID%-d", r); /* generate the ID */ /* ... */ |
The rand48
family of functions provides another alternative for pseudorandom numbers.
...
arc4random()
fits into a middle ground not covered by other subsystems such as the strong, slow, and resource expensive random devices described inrandom(4)
versus the fast but poor quality interfaces described inrand(3)
,random(3)
, anddrand48(3)
.
To achieve the best random numbers possible, an implementation-specific function must be used. When unpredictability really matters and speed is not an issue, such as in the creation of strong cryptographic keys, use a true entropy source such as /dev/random
or a hardware device capable of generating random numbers. Note that the /dev/random
device may block for a long time if there are not enough events going on to generate sufficient entropy.
In many cases, however, it will be acceptable to simply use a pseudorandom number generator from a cryptographic library (such as the Mersenne Twister) and seed it with data read from /dev/random
.
Compliant Solution (Windows)
...