0

Is there an equivalent of windows rand_s function on linux ? Indeed, a rand function but generating random number between 0 and UINT_MAX` (4294967295)

I have the solution of combine some digit rand() to create a big rand but I'm pretty sure the probabilities will no more be 1/UINT_MAX (because rand is a pseudo-random function and here I calculate with a sequence of rand call). For example, the following generates number between 0 and 4000000000:

unsigned int random = (unsigned int)((unsigned int)((rand()%4) * 1000000000) + (rand()%10) * 100000000 + (rand()%10) * 10000000 + (rand()%10) * 1000000 + (rand()%10) * 100000 + (rand()%10) * 10000 + (rand()%10) * 1000 + (rand()%10) * 100 + (rand()%10) * 10 + rand()%10);

Thanks in advance.


Here is a piece of code which works (Thanks a lot Dan)

#include <stdio.h>
#include <stdlib.h>

#include <fcntl.h>
#include <unistd.h>

int main()
{
    int i, randomSrc = open("/dev/urandom", O_RDONLY);
    unsigned int random;

    for(i=0;i<1000;i++)
    {
            read(randomSrc , &random, sizeof(unsigned int));
            printf("%u\n",random);
    }

    close(randomSrc);

    return 0;
}
Matthieu.P
  • 361
  • 2
  • 14
  • `INT_MAX` is 2147483647 on 32-bit platforms. Do you mean that, or maybe `UINT_MAX` (4294967295)? You won't reach 4294967296 unless you use longs. – interjay Oct 06 '14 at 23:38
  • You're right, sorry I'm a little tired. (But actually, a random between 0 and `INT_MAX` will be pretty good to ;) ) – Matthieu.P Oct 06 '14 at 23:43
  • Your method of generating a random number with a large range seems like a waste of entropy and clock cycles. If `(U)INT_MAX` is less than your desired range, why not just concatenate the outputs of 2 calls to `rand()`. Your assumption that the high bits are less random isn't true (anymore), I think. – Will Oct 06 '14 at 23:48
  • @Will AFAIK LCGs have lower randomness in the lower bits. – Matteo Italia Oct 07 '14 at 00:01

2 Answers2

2

You can use the same pseudo random number generator from stdlib.h but Linux also provides a real random number generator located at /dev/urandom which is a cryptographically secure random number generator that collects random bits called entropy bits. Here a SO article.

How to use /dev/random or urandom in C?

Community
  • 1
  • 1
Dan
  • 1,874
  • 1
  • 16
  • 21
1

The rand() function in most standard library implementations is a poor quality pseudo-random number generator. Calling it repeatedly makes its shortcomings even more conspicuous.

Since you state that you're using Linux, you have access to a much better pseudo-random number generator – from a system device rather than from a library function. For example:

FILE fd_urandom = fopen("/dev/urandom", "r");

. . .

int urand;
size_t count = fread(&urand, sizeof(int), 1, fd_urandom);
if (count < 1) {
  /* handle error */
}

. . .

fclose(fd_urandom);

The sizeof(int) must match the size of urand, so if you change urand to long, you need to change to sizeof(long) also.

I'm not sure how fast the fread(address, size, count, fd_urandom) is, but if you want a bunch of pseudo-random numbers, you're probably better off grabbing a bunch of numbers at a time and keeping them in a buffer.

/dev/urandom is a very high quality pseudo-random number generator, and good for most purposes. There is also a /dev/random, which is used only for certain security applications (such as encryption keys); it has the disadvantage that it may block if it doesn't think it can provide sufficiently "random" numbers.

Steve
  • 423
  • 2
  • 7
  • 17
  • Note I have noticed that urandom can cause significant delays, its not very fast for large quantities of numbers. If that is the case it can be best to read one number from urandom and use that as a seed for a good library implementation of a random generator. – Vality Oct 07 '14 at 00:35
  • @Vality I suspected that `/dev/urandom` might be a bit on the slow side. I haven't tried profiling it, but I've read the code and it *looks* computationally expensive. Using it to seed a good library pseudo-random number generator is a good way to speed up the code, but the generator should be something better than the usual library `rand()`. This question mentions an improved Mersenne Twister: http://stackoverflow.com/questions/4720822/best-pseudo-random-number-generator – Steve Oct 07 '14 at 06:24