Is there a function to generate a random int number in C? Or will I have to use a third party library?
32 Answers
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.

- 5,141
- 5
- 38
- 59

- 48,526
- 41
- 139
- 208
-
226+1 for simplicity, but it is probably a good idea to emphasize that srand() should only be called *once*. Also, in a threaded application, you might want to make sure that the generator's state is stored per thread, and seed the generator once for each thread. – RBerteig May 05 '09 at 00:37
-
3
-
49@trusktr, its complicated. Here's a reason: `time()` only changes once per second. If you seed from `time()`, for each call to `rand()`, then you will get the same value for every call during a single second. But the bigger reason is that the properties of `rand()` and functions like it are known best for the use case where they are seeded exactly once per run, and not on every single call. Depending on "randomness" with untested or unproven properties leads to trouble. – RBerteig Oct 01 '12 at 18:05
-
1
-
11@trusktr for a simple linear congruential generator (which is what `rand()` usually is) seeding with `rand()` would at best have no effect at all, and at worst would break the generator's known qualities. This is a deep subject. Start with reading [Knuth Vol 2](http://amzn.com/0321751043) Chapter 3 on random numbers as the best introduction to the mathematics and pitfalls. – RBerteig Oct 03 '12 at 21:15
-
3@user2600219 `time(NULL)` returns current time to the pointer if it's different than NULL. You can use some variable there, but it won't affect the result of `time()` and passed variable will be overwritten with current time. – gronostaj Apr 08 '14 at 11:39
-
26Avoid a compiler warning with a cast: `srand((unsigned int)time(NULL));` – GiovaMaster Oct 14 '14 at 12:16
-
-
2Since time is obviously not a great way to generate seed values, what would be a better way? – Taylor Oct 28 '15 at 21:24
-
1
-
14Keep in mind that this is still a weak way of seeing the PRNG. Just last year, a cryptolocker-type virus on Linux made the mistake of seeding with the time, and this *dramatically* reduced the search space. All you had to do was get a decent idea of when the infection occurred and then try seeds from around that time. Last I heard, the best source of randomness is /dev/urandom, which is, supposedly, seeded from a mashup of chaotic-ish sources like temperatures on the hardware. If all you really want, however, is for your program to act differently on each run, the above solution is fine. – Jemenake Feb 07 '16 at 20:15
-
1When I run that I get this: `guessing game.c:6:12: error: expected ')'` – tox123 Jun 11 '16 at 19:49
-
I've edited in a reference to another answer that explains how to generate a cryptographically secure random number in C, in case that's what the reader is looking for. – Scott Arciszewski Sep 13 '16 at 19:00
-
Do not use `time()` to seed if your program has a chance to be run twice or more within a second (which is likely to happen if it is called from a bash scripts). Save the seed into a file instead. – exebook Jun 15 '17 at 04:52
-
1given this is a top answer, you may want to update it to `random` and `srandom` - as recommended by the man pages – pyInTheSky Oct 12 '18 at 15:42
-
``random()`` and ``srandom()`` are glibc specific and do not seem to exist in ``stdlib.h`` e.g. on windows. The question was *not* linux specific. – BitTickler Nov 15 '18 at 06:04
-
@gronostaj - I have no influence on random generator, when I write srand(time(NULL)) ?! - is there no way to define a time span for 5 or for 10 seconds to get better random values ?! – dschinn1001 Jul 19 '19 at 01:28
-
@dschinn1001 Time span of what? `srand` seeds the pseudo-random number generator, ie. it gives it a starting point. If you call it twice with the same argument, then `rand` will produce exactly the same sequence of pseudo-random numbers. It's convenient to use current time for seed for not-security-critical purposes: it changes every second so it's unlikely to get the same sequence of numbers next time you run the program. But as soon as the attacker knows the seed, they can predict subsequent numbers. The seed doesn't have to be time, though, any number will do. – gronostaj Jul 19 '19 at 05:15
-
Don't the statements in your solution have to be inside a function (eg, `main`)? – Shammel Lee Apr 01 '20 at 20:19
-
@RBerteig Does the range of rand() include 0 and RAND_MAX or it give result between 0 and RAND_MAX excluding them? – Ravi Raj Aug 08 '20 at 16:16
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;
}
}

- 137,896
- 35
- 246
- 299
-
23It is a *common practice* alright, but not the correct one. See [this](http://stackoverflow.com/questions/2999075/generate-a-random-number-within-range/2999130#2999130) and [this](http://stackoverflow.com/questions/288739/generate-random-numbers-uniformly-over-entire-range/288869#288869). – Lazer Aug 01 '10 at 07:33
-
45@Lazer: That's why I said "though bear in mind that this throws off the uniformity somewhat". – Laurence Gonsalves Aug 02 '10 at 07:00
-
-1 for the same reason as @Lazer (although you did put the caveat the answer still has the potential to misguide) – necromancer Jul 13 '14 at 08:30
-
@LaurenceGonsalves How does this % operator work to print b/w range 0 to 19 can you explain. What's happening behind the screen? – HELP PLZ Aug 13 '14 at 10:03
-
-
3@AbhimanyuAryan The `%` is the modulus operator. It gives you the remainder of an integer division, so `x % n` will always give you a number between `0` and `n - 1` (as long as `x` and `n` are both positive). If you still find that confusing, try writing a program that has `i` count from 0 to 100, and prints out `i % n` for some `n` of your choosing smaller than 100. – Laurence Gonsalves Aug 14 '14 at 23:52
-
2@necromancer I went ahead and added a perfectly uniform solution. – Laurence Gonsalves Aug 15 '14 at 03:03
-
2@Lazer the second link you posted is actually still not perfectly uniform. Casting to a double and back doesn't help. The first link you posted has a perfectly uniform solution, though it will loop a *lot* for small upper bounds. I've added a perfectly uniform solution to this answer that shouldn't loop as much even for small upper bounds. – Laurence Gonsalves Aug 15 '14 at 03:31
-
-
1The lack of "uniformity" of `rand()%5` means that 0 will occur 858993460/858993459 times as often as 4. Compared to the other flaws of _any_ use of `rand()`, I would consider that trivial. A better reason (in my opinion) to deprecate `rand()%n` is that the low-order bits of a `rand()` sequence have a reputation for repeating with a much shorter period than the high-order bits, so if `n` is a power of 2 you may get a surprising pattern in whatever you use this for. – David K Jul 31 '15 at 12:44
-
@DavidK The amount of non-uniformity will depend on `RAND_MAX`, which can be as low as 32767. Still, I agree with your point that the non-uniformity is pretty insignificant for most applications. The quality of the PRNG is also highly implementation specific. If you need high-quality random numbers, you probably shouldn't be using `rand()`. – Laurence Gonsalves Jul 31 '15 at 18:19
-
@LaurenceGonsalves Yes, yes, and yes. The non-uniformity problem is worse with 2^15 than with 2^31 or 2^32 (good point!), but in the end, you'd better just not use `rand()` for anything where it really matters. – David K Jul 31 '15 at 20:10
-
BEWARE! This `randint(n)` function is clearly broken for `n=1`. It should produce results like flipping a coin, but it produces all zeros, so far. – daveloyall May 25 '17 at 17:15
-
1@daveloyall The comment says "Returns an integer in the range [0, n)". That's the half-open interval. In other words, 0 is included, but n is *not*. To flip a coin you need to call `randint(2)`. This is also consistent with the way `%` behaves. – Laurence Gonsalves May 25 '17 at 22:51
-
1@chux I believe you are correct. Not sure why I was using `long`, but probably had something to do with that multiply. I've updated the answer. – Laurence Gonsalves Apr 08 '18 at 22:10
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.

- 1,839
- 14
- 25

- 33,610
- 16
- 89
- 206
-
-
Just call `sodium_init()` at some point. Don't worry about the RNG, it uses the kernel's. – Scott Arciszewski Aug 29 '17 at 18:06
-
Note: I approved the recent edit for `sodium_init()` even though it's not necessarily part of my example because it's an important detail. – Scott Arciszewski Jul 18 '18 at 14:28
-
3Why is the use of OpenSSL and other userland PRNGs discouraged? The documentation for OpenSSL's `RAND_bytes()` says it's a cryptographically secure PRNG. – gsgx Jan 12 '21 at 01:30
-
@gsingh2011 Read https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ – Scott Arciszewski Apr 19 '21 at 03:18
-
@ScottArciszewski It says don't use OpenSSL in order not to introduce a second point of failure. – Motomotes Oct 18 '22 at 07:36
-
Correct. So don't use OpenSSL for randomness. It's not fork-safe. – Scott Arciszewski Oct 19 '22 at 05:45
Lets go through this. First we use the srand()
function to seed the randomizer. Basically, the computer can generate random numbers based on the number that is fed to srand()
. If you gave the same seed value, then the same random numbers would be generated every time.
Therefore, we have to seed the randomizer with a value that is always changing. We do this by feeding it the value of the current time with the time()
function.
Now, when we call rand()
, a new random number will be produced every time.
#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;
}

- 4,940
- 1
- 20
- 21

- 371
- 3
- 2
-
15Nice Code, but not a good idea to call 'srand(time(NULL));'. this method produce same number when called in a for loop. – RayOldProf Sep 19 '13 at 08:20
-
1Suggested edits involving code often get rejected. [Someone made one here](http://stackoverflow.com/review/suggested-edits/3563173) with the comment "algorithm was wrong. could produce bigger numbers than the maximum". Haven't evaluated the claim myself. – Martin Smith Dec 11 '13 at 23:47
-
1@Martin Smith Problems: 1) should be `else{ low_num=max_num; hi_num=min_num+1;` 2) fails when `hi_num - low_num > INT_MAX`. 3) Omits values in the rare situation `INT_MAX > hi_num - low_num > RAND_MAX`. – chux - Reinstate Monica Feb 24 '14 at 19:44
-
Good. I really liked the way you limited it: `(rand()%(hi_num-low_num))+low_num` – Wajahath Dec 17 '16 at 07:29
-
1Reseeding it like this will cause this function to produce the same number if it is called multiple times in the same second. If you really want to reseed it, then reseed only once per second. – Lux Aug 08 '17 at 23:52
-
1Minor: `hi_num = max_num + 1;` lacks protection against overflow. – chux - Reinstate Monica Apr 08 '18 at 21:55
-
1Significant weakness: ` result = (rand() % (hi_num - low_num)) + low_num;` only makes some sense if `RAND_MAX == INT_MAX`. `RAND_MAX` may be as small as 32767 even with a 4-byte `int`. Further, `hi_num - low_num` can readily overflow. – chux - Reinstate Monica Apr 08 '18 at 21:57
If you need better quality pseudo random numbers than what stdlib
provides, check out Mersenne Twister. It's faster, too. Sample implementations are plentiful, for example here.

- 975
- 1
- 9
- 13
-
5Don't use a Mersenne Twister, use something good like xoroshiro128+ or PCG. [(Relevant link.)](http://cs.stackexchange.com/questions/50059/why-is-the-mersenne-twister-regarded-as-good) – Veedrac Aug 14 '16 at 23:10
The standard C function is rand()
. It's good enough to deal cards for solitaire, but it's awful. Many implementations of rand()
cycle through a short list of numbers, and the low bits have shorter cycles. The way that some programs call rand()
is awful, and calculating a good seed to pass to srand()
is hard.
The best way to generate random numbers in C is to use a third-party library like OpenSSL. For example,
#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;
}
Why so much code? Other languages like Java and Ruby have functions for random integers or floats. OpenSSL only gives random bytes, so I try to mimic how Java or Ruby would transform them into integers or floats.
For integers, we want to avoid modulo bias. Suppose that we got some random 4 digit integers from rand() % 10000
, but rand()
can only return 0 to 32767 (as it does in Microsoft Windows). Each number from 0 to 2767 would appear more often than each number from 2768 to 9999. To remove the bias, we can retry rand()
while the value is below 2768, because the 30000 values from 2768 to 32767 map uniformly onto the 10000 values from 0 to 9999.
For floats, we want 53 random bits, because a double
holds 53 bits of precision (assuming it's an IEEE double). If we use more than 53 bits, we get rounding bias. Some programmers write code like rand() / (double)RAND_MAX
, but rand()
might return only 31 bits, or only 15 bits in Windows.
OpenSSL's RAND_bytes()
seeds itself, perhaps by reading /dev/urandom
in Linux. If we need many random numbers, it would be too slow to read them all from /dev/urandom
, because they must be copied from the kernel. It is faster to allow OpenSSL to generate more random numbers from a seed.
More about random numbers:
- Perl's Perl_seed() is an example of how to calculate a seed in C for
srand()
. It mixes bits from the current time, the process ID, and some pointers, if it can't read/dev/urandom
. - OpenBSD's arc4random_uniform() explains modulo bias.
- Java API for java.util.Random describes algorithms for removing bias from random integers, and packing 53 bits into random floats.

- 1,560
- 17
- 23
-
Thank you for this extended answer. Note that out of the 24 current answers to this question, you were the only one with an extra interpretation to deal with `float`/`double`, so I've clarified the question to stick to `int` numbers to avoid making it too broad. There are other C questions dealing specifically with `float`/`double` random values, so you may want to repost your second half of your answer to questions such as https://stackoverflow.com/questions/13408990/how-to-generate-random-float-number-in-c – Cœur Jul 14 '18 at 16:55
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 <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 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;
}

- 1,540
- 1
- 22
- 28
STL doesn't exist for C. You have to call rand
, or better yet, random
. These are declared in the standard library header stdlib.h
. rand
is POSIX, random
is a BSD spec function.
The difference between rand
and random
is that random
returns a much more usable 32-bit random number, and rand
typically returns a 16-bit number. The BSD manpages show that the lower bits of rand
are cyclic and predictable, so rand
is potentially useless for small numbers.
-
3@Neil - since all answers so far mention the STL, I suspect that the question was quick-edited to remove anunecessary reference. – Michael Burr May 04 '09 at 22:16
-
rand() isn't useless for small numbers - you can bitshift them out and use only the more random high bits if you really need to. – Chris Lutz May 04 '09 at 22:20
-
@Chris, you can if the size of the random number is known, but if the required size of the random number changes during runtime (such as shuffling a dynamic array etc) it would be difficult to work around such a caveat. – dreamlax May 04 '09 at 22:30
-
I can't find any random-function [here](http://www2.hs-fulda.de/~klingebiel/c-stdlib/stdlib.h.htm) :-( – kasia.b Mar 05 '14 at 15:21
-
@kasia.b in that link, there is `extern int rand(void);` and `extern void srand(unsigned int);`. – RastaJedi May 07 '16 at 08:23
Have a look at ISAAC (Indirection, Shift, Accumulate, Add, and Count). Its uniformly distributed and has an average cycle length of 2^8295.

- 9,954
- 2
- 42
- 50
-
2ISAAC is an interesting RNG because of its speed but has not received serious cryptographic attention yet. – user2398029 Apr 13 '14 at 22:55
This is a good way to get a random number between two numbers of your choice.
#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));
}
Output the first time: 39
Output the second time: 61
Output the third time: 65
You can change the values after randnum
to whatever numbers you choose, and it will generate a random number for you between those two numbers.

- 7,860
- 7
- 40
- 71

- 59
- 1
- 1
I had a serious issue with pseudo random number generator in my recent application: I repeatedly called my C program via a Python script and I was using as seed the following code:
srand(time(NULL))
However, since:
- rand will generate the same pseudo random sequence give the same seed in srand (see
man srand
); - As already stated, time function changes only second from second: if your application is run multiple times within the same second,
time
will return the same value each time.
My program generated the same sequence of numbers. You can do 3 things to solve this problem:
mix time output with some other information changing on runs (in my application, the output name):
srand(time(NULL) | getHashOfString(outputName))
I used djb2 as my hash function.
Increase time resolution. On my platform,
clock_gettime
was available, so I use it:#include<time.h> struct timespec nanos; clock_gettime(CLOCK_MONOTONIC, &nanos) srand(nanos.tv_nsec);
Use both methods together:
#include<time.h> struct timespec nanos; clock_gettime(CLOCK_MONOTONIC, &nanos) srand(nanos.tv_nsec | getHashOfString(outputName));
Option 3 ensures you (as far as I know) the best seed randomness, but it may create a difference only on very fast application. In my opinion option 2 is a safe bet.
-
Even with these heuristics, don't rely on rand() for cryptographic data. – domenukk Jul 26 '19 at 16:03
-
`rand()` should not be used for cryptographic data, I agree. At least for me, my application didn't involve cryptographic data, so for me it was ok the given method. – Koldar Jul 26 '19 at 19:12
This is hopefully a bit more random than just using 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());
}
-
1adding srand(rand()) does not increase the randomness of the sequence if this program is executed multiple times within 1 second. time(NULL) will still return the same value for each of them, the first rand() will return the same long, and the second call to srand() will be with the same value, resulting in still having the same random sequence. Use of the address of argc might help, only if it is guaranteed that this address will be different on every execution of the program, which is not always true. – theferrit32 Mar 01 '18 at 21:24
C Program to generate random number between 9 and 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);
}
In general we can generate a random number between lowerLimit and upperLimit-1
i.e lowerLimit is inclusive or say r ∈ [ lowerLimit, upperLimit )

- 1,197
- 8
- 21
-
@Pang That's what I clearly mentioned BETWEEN 9 and 50 not FROM 9 and 50. – skt7 Aug 22 '17 at 04:35
-
4
Well, STL is C++, not C, so I don't know what you want. If you want C, however, there is the rand()
and srand()
functions:
int rand(void);
void srand(unsigned seed);
These are both part of ANSI C. There is also the random()
function:
long random(void);
But as far as I can tell, random()
is not standard ANSI C. A third-party library may not be a bad idea, but it all depends on how random of a number you really need to generate.

- 73,191
- 16
- 130
- 183
You want to use rand()
. Note (VERY IMPORTANT): make sure to set the seed for the rand function. If you do not, your random numbers are not truly random. This is very, very, very important. Thankfully, you can usually use some combination of the system ticks timer and the date to get a good seed.

- 7,860
- 7
- 40
- 71

- 38,903
- 3
- 77
- 117
-
7Two points a) your random numbers are not "truly" random, no matter how you seed the generator. And b) it is very convenient to have the pseudo-random sequence always be the same in many circumstances - for testing, for example. – May 04 '09 at 22:19
-
20if it's VERY IMPORTANT that your number be truly random, you shouldn't be using the rand() function. – tylerl May 04 '09 at 22:19
-
2The values from rand are not at all "truly" random no matter if you set the seed or not. Given a known seed the sequence is predictable. "Truly" random number generation is difficult. There is no entropy involved with rand. – dreamlax May 04 '09 at 22:20
-
Okay, good points all; still, if you don't set your seed your numbers won't even be pseudo-random. – Paul Sonier May 04 '09 at 22:25
-
2Of course they will - the generator is seeded for you by the library (probably to zero, but that's a valid seed). – May 04 '09 at 22:29
-
1I don't particularly count "pseudo-random according to a known algorithm and a known seed" to be fulfilling the qualifications for any level of "randomness". :-) – Paul Sonier May 04 '09 at 22:39
-
5Ah, but known algorithm/known seed is essential to debugging any program that uses random numbers. It isn't unusual to log the seed used along with a simulation run so that it can be recreated for more detailed analysis. Not calling srand() at all is equivalent to calling srand(1). – RBerteig May 05 '09 at 00:41
FWIW, the answer is that yes, there is a stdlib.h
function called rand
; this function is tuned primarily for speed and distribution, not for unpredictability. Almost all built-in random functions for various languages and frameworks use this function by default. There are also "cryptographic" random number generators that are much less predictable, but run much slower. These should be used in any sort of security-related application.
On modern x86_64 CPUs you can use the hardware random number generator via _rdrand64_step()
Example 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

- 13,865
- 7
- 86
- 158
-
1That should be used in a retry loop, not an `if`. Temporary failure is expected on real CPUs, if multiple threads are pulling random numbers quickly. See [RDRAND and RDSEED intrinsics on various compilers?](https://stackoverflow.com/a/72265912) for better wrapper functions. – Peter Cordes May 16 '22 at 21:41
rand()
is the most convenient way to generate random numbers.
You may also catch random number from any online service like random.org.

- 74,352
- 26
- 153
- 180

- 1,415
- 3
- 16
- 30
-
3*You may also catch random number from any online service like random.org* Bounty if you include a portable, efficient way to do this in C. – MD XF Feb 27 '17 at 01:33
#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]);
}

- 7,860
- 7
- 40
- 71

- 434
- 4
- 10
-
One note: it is theoretically possible for this function to hang for an infinite amount of time, depending on the system's implementation of `rand`. – Lux Jul 19 '17 at 22:38
Despite all the people suggestion rand()
here, you don't want to use rand()
unless you have to! The random numbers that rand()
produces are often very bad. To quote from the Linux man page:
The versions of
rand()
andsrand()
in the Linux C Library use the same random number generator asrandom(3)
andsrandom(3)
, so the lower-order bits should be as random as the higher-order bits. However, on older rand() implementations, and on current implementations on different systems, the lower-order bits are much less random than the higher-order bits. Do not use this function in applications intended to be portable when good randomness is needed. (Userandom(3)
instead.)
Regarding portability, random()
is also defined by the POSIX standard for quite some time now. rand()
is older, it appeared already in the first POSIX.1 spec (IEEE Std 1003.1-1988), whereas random()
first appeared in POSIX.1-2001 (IEEE Std 1003.1-2001), yet the current POSIX standard is already POSIX.1-2008 (IEEE Std 1003.1-2008), which received an update just a year ago (IEEE Std 1003.1-2008, 2016 Edition). So I would consider random()
to be very portable.
POSIX.1-2001 also introduced the lrand48()
and mrand48()
functions, see here:
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
And a pretty good pseudo random source is the arc4random()
function that is available on many systems. Not part of any official standard, appeared in BSD around 1997 but you can find it on systems like Linux and macOS/iOS.

- 125,244
- 33
- 244
- 253
-
-
@BjörnLindqvist Windows is also no POSIX system; it's pretty much the only system on the market that does not support at least the base POSIX APIs (which even locked down systems like iOS do support). Windows is only supporting `rand()` as it is also required by the C standard. For anything else, you need a special solution for Windows only, just as usual. `#ifdef _WIN32` is the phrase you will see most often in cross-platform code that wants to support Windows as well as usually there is one solution that works with all systems and one that is required for Windows only. – Mecki Jan 13 '20 at 09:32
#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;
}

- 7,860
- 7
- 40
- 71

- 43
- 1
#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;
}

- 3,863
- 1
- 25
- 16
For Linux C applications:
This is my reworked code from an answer above that follows my C code practices and returns a random buffer of any size (with proper return codes, etc.). Make sure to call urandom_open()
once at the beginning of your program.
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;
}
}

- 3,633
- 3
- 21
- 23
Here is my approach (a wrapper around rand()
):
I also scale to allow a case where min is INT_MIN
and max is INT_MAX
, which is normally not possible with rand()
alone since it returns values from 0
to RAND_MAX
, inclusive (1/2 that range).
Use it like this:
const int MIN = 1;
const int MAX = 1024;
// Get a pseudo-random number between MIN and MAX, **inclusive**.
// Seeding of the pseudo-random number generator automatically occurs
// the very first time you call it.
int random_num = utils_rand(MIN, MAX);
Definitions and doxygen descriptions:
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
/// \brief Use linear interpolation to rescale, or "map" value `val` from range
/// `in_min` to `in_max`, inclusive, to range `out_min` to `out_max`, inclusive.
/// \details Similar to Arduino's ingenious `map()` function:
/// https://www.arduino.cc/reference/en/language/functions/math/map/
///
/// TODO(gabriel): turn this into a gcc statement expression instead to prevent the potential for
/// the "double evaluation" bug. See `MIN()` and `MAX()` above.
#define UTILS_MAP(val, in_min, in_max, out_min, out_max) \
(((val) - (in_min)) * ((out_max) - (out_min)) / ((in_max) - (in_min)) + (out_min))
/// \brief Obtain a pseudo-random integer value between `min` and `max`, **inclusive**.
/// \details 1. If `(max - min + 1) > RAND_MAX`, then the range of values returned will be
/// **scaled** to the range `max - min + 1`, and centered over the center of the
/// range at `(min + max)/2`. Scaling the numbers means that in the case of scaling,
/// not all numbers can even be reached. However, you will still be assured to have
/// a random distribution of numbers across the full range.
/// 2. Also, the first time per program run that you call this function, it will
/// automatically seed the pseudo-random number generator with your system's
/// current time in seconds.
/// \param[in] min The minimum pseudo-random number you'd like, inclusive. Can be positive
/// OR negative.
/// \param[in] max The maximum pseudo-random number you'd like, inclusive. Can be positive
/// OR negative.
/// \return A pseudo-random integer value between `min` and `max`, **inclusive**.
int utils_rand(int min, int max)
{
static bool first_run = true;
if (first_run)
{
// seed the pseudo-random number generator with the seconds time the very first run
time_t time_now_sec = time(NULL);
srand(time_now_sec);
first_run = false;
}
int range = max - min + 1;
int random_num = rand(); // random num from 0 to RAND_MAX, inclusive
if (range > RAND_MAX)
{
static_assert(
sizeof(long int) > sizeof(int),
"This must be true or else the below mapping/scaling may have undefined overflow "
"and not work properly. In such a case, try casting to `long long int` instead of "
"just `long int`, and update this static_assert accordingly.");
random_num = UTILS_MAP((long int)random_num, (long int)0, (long int)RAND_MAX, (long int)min,
(long int)max);
return random_num;
}
// This is presumably a faster approach than the map/scaling function above, so do this faster
// approach below whenever you don't **have** to do the more-complicated approach above.
random_num %= range;
random_num += min;
return random_num;
}
See also:
- [I discovered this Q&A after writing my answer above, but it is obviously very relevant, and they do the same thing I do for the non-scaling range case] How do I get a specific range of numbers from rand()?
- [I NEED TO STUDY AND READ THIS ANSWER MORE STILL--seems to have some good points about retaining good randomness by not using modulus alone] How do I get a specific range of numbers from rand()?

- 36,492
- 15
- 194
- 265
If you need, say, 128 secure random bits, the RFC 1750 compliant solution is to read hardware source that is known to generate useable bits of entropy (such as a spinning disk). Better yet, good implementations should combine multiple sources using a mixing function, and finally de-skew the distribution of their output, by re-mapping or deleting outputs.
If you need more bits than that, the compliant thing to do is start with sequence of 128 secure random bits and stretch it to a desired length, map it to human readable text, etc.
If you want to generate a secure random number in C I would follow the source code here:
Note that for Windows BCryptGenRandom is used, not CryptGenRandom which has become unsecure within the past two decades. You can confirm for yourself that BCryptGenRandom is compliant with RFC 1750.
For POSIX-compliant operating systems, e.g. Ubuntu (a flavor of Linux), you can simply read from /dev/urandom
or /dev/random
, which is a file-like interface to a device that generates bits of entropy by combining multiple sources in an RFC 1750 compliant fashion. You can read a desired number of bytes from these "files" with read
or fread
just like you would any other file, but note that reads from /dev/random
will block until a enough new bits of entropy are available, whereas /dev/urandom
will not, which can be a security issue. You can get around that by checking the size of the available entropy pool, either my reading from entropy_avail
, or by using ioctl
.

- 117
- 6
The glibc-specific function (that should be found in most of Linux environments) related to this is random()
, or you may be interested with its thread-safe version random_r()
. You have to initialize the struct random_data
with initstate_r()
prior to passing it to random_r()
.
Here is quick code sample :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void xxx (void) {
unsigned int seed = (unsigned int) time(NULL);
char rnd_state[17] = {0};
struct random_data rnd_st_buf = {0};
initstate_r(seed, &rnd_state[0], 17, &rnd_st_buf);
for(size_t idx = 0; idx < 8; idx++) {
int32_t rnd_int = 0;
char rnd_seq_str[6] = {0};
random_r(&rnd_st_buf, &rnd_int);
memcpy((char *)&rnd_seq_str[0], (char *)&rnd_int, 4);
printf("random number : 0x%08x, \n", rnd_int);
}
}

- 703
- 8
- 17
You can generate random chars, then view them as int :
#include <stdlib.h>
#include <stdio.h>
typedef double rand_type; // change double to int
rand_type my_rand() {
char buff[sizeof(rand_type)];
for (size_t i = 0 ; i < sizeof(rand_type) ; ++i)
buff[i] = (char) rand();
return *(rand_type *) buff;
}
int main() {
int i ; // srand as you want
for (i = 0 ; i < 10 ; ++i)
printf("%g\n", my_rand()); // change %g to %d
return 0 ;
}
-
I don't see anything wrong with this answer, so i upvoted it. I appreciate that RNG's should be seeded using time or some other entry device, but then again sometimes you want something to *appear* random and chaotic, but you may actually *want* the randomness to be predictable and deterministic - say for instance to reproduce a bug. So I don't think there's anything wrong with this answer. – Owl Apr 05 '22 at 00:33
You can also use mathgl library #include <mgl2/mgl_cf.h>
(though first you need to install it, I own installed through MSYS2) with function mgl_rnd()
. It also have kinds of distribution like uniform, guassian and more. It's ez to use. But I dont know about it's characteristic.

- 330
- 1
- 11
Hearing a good explanation of why using rand()
to produce uniformly distributed random numbers in a given range is a bad idea, I decided to take a look at how skewed the output actually is. My test case was fair dice throwing. Here's the C code:
#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);
}
and here's its output:
$ 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%
I don't know how uniform you need your random numbers to be, but the above appears uniform enough for most needs.
Edit: it would be a good idea to initialize the PRNG with something better than time(NULL)
.

- 542
- 6
- 9
-
rand() can fail other randomness tests, such as the [diehard tests](https://en.wikipedia.org/wiki/Diehard_tests). rand() differs from platform to platform; rand() values from GNU/Linux might be better than values from BSD or Windows. – George Koehler Jul 08 '15 at 01:37
-
2
-
Depends on the purpose and the threat/risk model. For cryptographically strong RNG - sure, use RDRAND (or RDSEED). For a simple dice thrower (not casino-level) IMHO the above should suffice. The keyword is "good _enough_". – Mouse Aug 29 '16 at 03:23
-
1`%6` means your randomness includes higher bits, not just the low few like `%8` would. So one of the big downsides of an LCG-based `rand()` is avoided. Of course, the big problem with an LCG isn't overall distribution in the long term, it's things like the low bit alternating from odd to even every time, for a very simple LCG. Incrementing a counter from 0 to n would also provide a very uniform distribution, but not random. So your test doesn't distinguish a random sequence from a nearly-linear sequence, and thus can't tell us very much about many types of potential problems, only bias. – Peter Cordes May 16 '22 at 21:51
My minimalistic solution should work for random numbers in range [min, max)
. Use srand(time(NULL))
before invoking the function.
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));
}

- 5,402
- 3
- 19
- 21

- 10,759
- 11
- 88
- 143
Try this, I put it together from some of the concepts already referenced above:
/*
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;
}
-
19This code is not good. Calling `srand()` every time you want to call `rand()` is a terrible idea. Since `time()` typically returns a value in __seconds__ calling this function rapidly will return the same "random" value. – Blastfurnace Sep 14 '13 at 21:08
-
3This function would get confused with Unix's `random()` function. – George Koehler Jul 04 '15 at 00:54
You can use the concept of a dangling pointer.
A pointer pointing to a memory location that has been deleted (or freed) is called dangling pointer.
It will show random values while printing.

- 1,133
- 8
- 10
-
4Doing this is [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) and could cause your program to crash. – dbush Aug 18 '20 at 03:38
-
1Just because it worked for you doesn't mean it will work for everyone. That's part of how undefined behavior can manifest. – dbush Aug 19 '20 at 03:01