Is there a function to generate a random int number in C? Or will I have to use a third party library?
If your system supports the arc4random family of functions I would recommend using those instead the standard rand
function.
The arc4random
family includes:
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
returns a random 32-bit unsigned integer.
arc4random_buf
puts random content in it's parameter buf : void *
. The amount of content is determined by the bytes : size_t
parameter.
arc4random_uniform
returns a random 32-bit unsigned integer which follows the rule: 0 <= arc4random_uniform(limit) < limit
, where limit is also an unsigned 32-bit integer.
arc4random_stir
reads data from /dev/urandom
and passes the data to arc4random_addrandom
to additionally randomize it's internal random number pool.
arc4random_addrandom
is used by arc4random_stir
to populate it's internal random number pool according to the data passed to it.
If you do not have these functions, but you are on Unix, then you can use this code:
/* This is C, not C++ */
#include
#include
#include
#include
#include
#include /* exit */
#include /* 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 sizeof(long) bytes (usually 8) into *buf, which points to buf_impl */
read(urandom_fd, buf, sizeof(long));
return buf_impl;
}
The urandom_init
function opens the /dev/urandom
device, and puts the file descriptor in urandom_fd
.
The urandom
function is basically the same as a call to rand
, except more secure, and it returns a long
(easily changeable).
However, /dev/urandom
can be a little slow, so it is recommended that you use it as a seed for a different random number generator.
If your system does not have a /dev/urandom
, but does have a /dev/random
or similar file, then you can simply change the path passed to open
in urandom_init
. The calls and APIs used in urandom_init
and urandom
are (I believe) POSIX-compliant, and as such, should work on most, if not all POSIX compliant systems.
Notes: A read from /dev/urandom
will NOT block if there is insufficient entropy available, so values generated under such circumstances may be cryptographically insecure. If you are worried about that, then use /dev/random
, which will always block if there is insufficient entropy.
If you are on another system(i.e. Windows), then use rand
or some internal Windows specific platform-dependent non-portable API.
Wrapper function for urandom
, rand
, or arc4random
calls:
#define RAND_IMPL /* urandom(see large code block) | rand | arc4random */
int myRandom(int bottom, int top){
return (RAND_IMPL() % (top - bottom)) + bottom;
}