How to generate a random int in C?
Note: Don't use
rand()
for security. If you need a cryptographically secure number, see this answer instead.
#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.
On Linux, you might prefer to use random and srandom.
The rand()
function in <stdlib.h>
returns a pseudo-random integer between 0 and RAND_MAX
. You can use srand(unsigned int seed)
to set a seed.
It's common practice to use the %
operator in conjunction with rand()
to get a different range (though bear in mind that this throws off the uniformity somewhat). For example:
/* random int between 0 and 19 */int r = rand() % 20;
If you really care about uniformity you can do something like this:
/* 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; }}
If you need secure random characters or integers:
As addressed in how to safely generate random numbers in various programming languages, you'll want to do one of the following:
- Use libsodium's
randombytes
API - Re-implement what you need from libsodium's sysrandom implementation yourself, very carefully
- More broadly, use
/dev/urandom
, not/dev/random
. Not OpenSSL (or other userspace PRNGs).
For example:
#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()
is cryptographically secure and unbiased.