How to generate a random int in C?

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.


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;
  }
}

Tags:

C

Random