I need a 'good' way to initialize the pseudo-random number generator in C++. I've found an article that states:
In order to generate random-like numbers, srand is usually initialized to some distinctive value, like those related with the execution time. For example, the value returned by the function time (declared in header ctime) is different each second, which is distinctive enough for most randoming needs.
Unixtime isn't distinctive enough for my application. What's a better way to initialize this? Bonus points if it's portable, but the code will primarily be running on Linux hosts.
I was thinking of doing some pid/unixtime math to get an int, or possibly reading data from /dev/urandom
.
Thanks!
EDIT
Yes, I am actually starting my application multiple times a second and I've run into collisions.
Include the header at the top of your program, and write:
In your program before you declare your random number. Here is an example of a program that prints a random number between one and ten:
Best way is to use another pseudorandom number generator. Mersenne twister (and Wichmann-Hill) is my recommendation.
http://en.wikipedia.org/wiki/Mersenne_twister
The best answer is to use the Boost random number stuff. Or if you have access to C++11 use the
<random>
header.But if we are talking about
rand()
andsrand()
The best way is just to use
time()
:Be sure to do this at the beginning of your program, and not every time you call
rand()
!Every time you start up, time() will return a unique value (unless you start the application multiple times a second). In 32 bit systems, it will only repeat every 60 years or so.
I know you don't think time is unique enough but I find that hard to believe. But I have been known to be wrong.
If you are starting a lot of copies of your application simultaneously you could use a timer with a finer resolution. But then you run the risk of a shorter time period before the value repeats.
OK, so if you really think you are starting multiple applications a second.
Then use a finer grain on the timer.
As long as your program is only running on Linux (and your program is an ELF executable), you are guaranteed that the kernel provides your process with a unique random seed in the ELF aux vector. The kernel gives you 16 random bytes, different for each process, which you can get with
getauxval(AT_RANDOM)
. To use these forsrand
, use just anint
of them, as such:It may be possible that this also translates to other ELF-based systems. I'm not sure what aux values are implemented on systems other than Linux.
For those using Visual Studio here's yet another way:
Maybe a bit overkill but works well for quick intervals. gettimeofday function found here.
Edit: upon further investigation rand_s might be a good alternative for Visual Studio, it's not just a safe rand(), it's totally different and doesn't use the seed from srand. I had presumed it was almost identical to rand just "safer".
To use rand_s just don't forget to #define _CRT_RAND_S before stdlib.h is included.
i suggest you see unix_random.c file in mozilla code. ( guess it is mozilla/security/freebl/ ...) it should be in freebl library.
there it uses system call info ( like pwd, netstat ....) to generate noise for the random number;it is written to support most of the platforms (which can gain me bonus point :D ).