boost::random generate the same number every time - c++

main .cpp
#include "stdafx.h"
#include "random_generator.h"
int
main ( int argc, char *argv[] )
{
cout.setf(ios::fixed);
base_generator_type base_generator;
int max = pow(10, 2);
distribution_type dist(1, max);
boost::variate_generator<base_generator_type&,
distribution_type > uni(base_generator, dist);
for ( int i=0; i<10; i++ ) {
//cout << random_number(2) << endl;
cout << uni() << endl;
}
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
random_gemerator.h
#include "stdafx.h"
#include <boost/random.hpp>
#include <boost/generator_iterator.hpp>
typedef boost::mt19937 base_generator_type;
typedef boost::lagged_fibonacci19937 fibo_generator_type;
typedef boost::uniform_int<> distribution_type;
typedef boost::variate_generator<fibo_generator_type&,
distribution_type> gen_type;
int
random_number ( int bits )
{
fibo_generator_type fibo_generator;
int max = pow(10, bits);
distribution_type dist(1, max);
gen_type uni(fibo_generator, dist);
return uni();
} /* ----- end of function random_number ----- */
stdafx.h
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
every time I run it, it all generate the same number sequence
like 77, 33,5, 22 , ...
how to use boost:random correctly?
that is it. but maybe have a little problem, like the following:
it seems sound
get_seed(); for (;;) {cout << generate_random() << endl; } // is ok
it genereate the same random number
int get_random() {get_seed();return generate_random();} for (;;) {cout << get_random() <<endl;} // output the same random number yet

if you want the sequence of random numbers to change every time you run your program, you need to change the random seed by initializing it with the current time for instance
you will find an example there, excerpt:
/*
* Change seed to something else.
*
* Caveat: std::time(0) is not a very good truly-random seed. When
* called in rapid succession, it could return the same values, and
* thus the same random number sequences could ensue. If not the same
* values are returned, the values differ only slightly in the
* lowest bits. A linear congruential generator with a small factor
* wrapped in a uniform_smallint (see experiment) will produce the same
* values for the first few iterations. This is because uniform_smallint
* takes only the highest bits of the generator, and the generator itself
* needs a few iterations to spread the initial entropy from the lowest bits
* to the whole state.
*/
generator.seed(static_cast<unsigned int>(std::time(0)));

You need to seed your random number generator so it doesn't start from the same place each time.
Depending on what you are doing with the numbers, you may need to put some thought into how you choose your seed value. If you need high quality randomness (if you are generating cryptographic keys and want them fairly secure), you will need a good seed value. If this were Posix, I would suggest /dev/random - but you look to be using Windows so I'm not sure what a good seed source would be.
But if you don't mind a predictable seed (for games, simulations, etc.), a quick and dirty seed is the current timestamp returned by time().

If you are running on a 'nix system, you could always try something like this;
int getSeed()
{
ifstream rand("/dev/urandom");
char tmp[sizeof(int)];
rand.read(tmp,sizeof(int));
rand.close();
int* number = reinterpret_cast<int*>(tmp);
return (*number);
}
I'm guessing seeding the random number generator this way is faster than simply reading the /dev/urandom (or /dev/random) for all your random number needs.

You can use the boost::random::random_device class either as-is, or to seed your other generator.
You can get a one-off random number out of it with a simple:
boost::random::random_device()()

Related

C++ Password Generator Generates Same Password [duplicate]

In this rather basic C++ code snippet involving random number generation:
include <iostream>
using namespace std;
int main() {
cout << (rand() % 100);
return 0;
}
Why am I always getting an output of 41? I'm trying to get it to output some random number between 0 and 100. Maybe I'm not understanding something about how the rand function works?
You need to change the seed.
int main() {
srand(time(NULL));
cout << (rand() % 101);
return 0;
}
This srand thing also works for C.
See also:
http://xkcd.com/221/
For what its worth you are also only generating numbers between 0 and 99 (inclusive). If you wanted to generate values between 0 and 100 you would need.
rand() % 101
in addition to calling srand() as mentioned by others.
srand() seeds the random number generator. Without a seed, the generator is unable to generate the numbers you are looking for. As long as one's need for random numbers is not security-critical (e.g. any sort of cryptography), common practice is to use the system time as a seed by using the time() function from the <ctime> library as such: srand(time(0)). This will seed the random number generator with the system time expressed as a Unix timestamp (i.e. the number of seconds since the date 1/1/1970). You can then use rand() to generate a pseudo-random number.
Here is a quote from a duplicate question:
The reason is that a random number generated from the rand() function isn't
actually random. It simply is a transformation. Wikipedia gives a better
explanation of the meaning of pseudorandom number generator: deterministic
random bit generator. Every time you call rand() it takes the seed and/or the
last random number(s) generated (the C standard doesn't specify the algorithm
used, though C++11 has facilities for specifying some popular algorithms), runs
a mathematical operation on those numbers, and returns the result. So if the
seed state is the same each time (as it is if you don't call srand with a truly
random number), then you will always get the same 'random' numbers out.
If you want to know more, you can read the following:
http://www.dreamincode.net/forums/topic/24225-random-number-generation-102/
http://www.dreamincode.net/forums/topic/29294-making-pseudo-random-number-generators-more-random/
You are not seeding the number.
Use This:
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
srand(static_cast<unsigned int>(time(0)));
cout << (rand() % 100) << endl;
return 0;
}
You only need to seed it once though. Basically don't seed it every random number.
random functions like borland complier
using namespace std;
int sys_random(int min, int max) {
return (rand() % (max - min+1) + min);
}
void sys_randomize() {
srand(time(0));
}
"srand(time(NULL));" as 1st line at "main()" won't help you if you're using "rand()" at static init. somewhere. You better create "struct rnd_init { rnd_init() { srand (time (nullptr)); } }" named whatever suits you, as a static var at the scope where "rand()" is being used: at some constructor, or whatever.

Why use "time" in srand?

I like to learn by screwing around with code, recently I copied and pasted a random number generator code. Then I removed all the lines of code that were not "necessary" to make the executable work to generate a random number. The final straw was me deleting "time" from srand.
srand((unsigned) time(0));
What is the point of "time(0)" here?
Does it use the time that the program is opened to generate the seed for the random number? Is that why removing it (time) makes it not work? Because then it doesn't have a seed?
Also...
include <stdlib.h>
include <stdio.h>
include <time.h>
int main()
{
srand((unsigned) time(0));
printf("Your dice has been rolled! You got:");
int result = 1 + (rand() % 20);
printf("%d", result);
}
that's the whole code and I noticed it used the "rand" result for output. Does the "rand" pull the seed from "srand"?
If you don’t “seed” the random number generator (or if you use the same seed value), you’ll get the same set of pseudorandom numbers.
Using the current time is an easy way to get a different seed every time.
The effect of srand cannot cross threads, so the random number seed should be set once on each thread. #Buddy said that using time(0) is the most convenient way to do this, and each call will get a different seed.Of course you can use an atomic variable .
std::atomic<int> seek(2374213); //init whatever you like
void thread1fun()
{
srand(++seek);
//...
int rand_num = rand();
}
void thread2fun()
{
srand(++seek);
//...
int rand_num = rand();
}

C++ fast random number generator [duplicate]

This question already has answers here:
C++ generating random numbers
(11 answers)
Closed 8 years ago.
I'm sorry if this is kind of a dumb question, but I'm new to c++, and honestly can't find the answer;
When I use rand(), of course I have to first use srand().
At first i'd just import <ctime> and do srand(time()), and this worked. But if I called rand() more than once a second - how often time() changes - then I'd get the same answer. So for instance;
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
bool x = true;
while(x == true)
{
int num = 1;
srand(time(NULL));
num = rand();
cout<<num%10<<endl;
}
}
Might produce something like, 6666666666777777777700000000003333333333
Which is no good for my purposes - I'd prefer something like 163509284749301935766.
You should only seed the random number generator once. Right now you are seeding it in the loop and using time(NULL) just means the seed changes once per second which gives you the bad output you have described.
DO this instead:
int main()
{
bool x = true;
int num = 1;
srand(time(NULL));
while(x == true)
{
num = rand();
cout<<num%10<<endl;
}
}
And if you really care about the random numbers generated you might want to use something other than rand(). The reason is that rand() has poor statistical properties for pseudo random number generation, it is often implemented as a Linear congruential generator. If you need high quality randomness then you should prefer something else such as the new c++ random number generators http://en.cppreference.com/w/cpp/numeric/random.
In fact there's even a report on depreciating the old rand() to try to push people to use the newer c++ standard library random functions.
In this particular case you take a modulus which causes a few subtle problems:
num = rand();
cout<<num%10<<endl;
Even if rand() was perfect if the modulus here isn't a divisor of the maximum value returned by rand() you will get a non-uniform distribution as a result. Here's a quick explanation, say rand() returned values in the range of [0,25] then taking the modulus would do the following.
before after modulus
[0-9] [0-9]
[10-19] [0-9]
[20-25] [0-5]
You'll see that you are more likely to get [0-5] than [6-9] which means you now no longer have a uniform number being generated. Note that this small range is for educational purposes only, the maximum value of rand() is mandated by the standard to be at least 32767. However it illustrates an important point, the larger the maximum generated number the better.
This uniformity of distribution problem aside the modulus has the particularly insidious effect of decreasing the quality of the pseudo-randomness even further for some implementations.
Using std::uniform_int_distribution avoids many problems so I would recommend changing your existing code to use the new library. Doing so would look like this:
#include <iostream>
#include <random>
using namespace std;
int main()
{
std::default_random_engine generator;
generator.seed( /* your seed for the RNG goes here */ );
std::uniform_int_distribution<int> distribution(0,9);//note the min and max parameters are inclusive here
while(true)
{
cout << distribution(generator) << endl;
}
}
A function f() that would generate random numbers in range [low,high] can be easily, robustly and safely defined with c++11 library facilities :
#include <random>
#include <iostream>
int f(int low, int high)
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(low, high);
return dis(gen);
}
std::uniform_int_distribution will give you a random number in your range (eg (0,9) ) this way
On the rationale behind refraining from using the old rand you can check this

C++ random number between 2 numbers reset

The function below runs, but always returns the same numbers each time I run the program. Is there a way to generate random numbers that are different each time I run the program?
int getrand(int min,int max){
int rnum = rand()%(max-min)+min;
return rnum;
}
You might like to use the high-quality standard library random number generation facilities:
#include <random>
typedef std::mt19937 rng_type;
std::uniform_int_distribution<rng_type::result_type> udist(min, max);
rng_type rng;
int main()
{
// seed rng first:
rng_type::result_type const seedval = 4; // or implement a good get_seed()?
rng.seed(seedval);
rng_type::result_type random_number = udist(rng);
return random_number;
}
try with this:
/* initialize random seed: */
srand ( time(NULL) );
somewhere when your program start ( absolutely not in your getrand() function ). This will force the generator to start each time with a different seed.
Seems like you forgot to call srand.
Pseudo random number generators need to be "seeded" before you use them; the default seed is the same every time, so you get the same sequence.
Typically you use something like srand(time(NULL)), but this fails if you run the program again within a second.
It's also good to use up a random number or two after seeding, since the first few values are highly correlated with the seed itself.
a simple solution to randomize once would be:
int getrand(int min, int max) {
static bool init = false;
if (!init) {
srand(time(NULL));
init = true;
}
return rand()%(max-min)+min;
}
You need to initiate the seed. Check out srand. Also, try boost if you want:
boost::lagged_fibonacci607 base_prng(seed);
boost::variate_generator<boost::lagged_fibonacci607&,boost::uniform_smallint<> > prng(base_prng,boost::uniform_smallint<>(min,max))

Recommended way to initialize srand?

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.
This is what I've used for small command line programs that can be run frequently (multiple times a second):
unsigned long seed = mix(clock(), time(NULL), getpid());
Where mix is:
// Robert Jenkins' 96 bit Mix Function
unsigned long mix(unsigned long a, unsigned long b, unsigned long c)
{
a=a-b; a=a-c; a=a^(c >> 13);
b=b-c; b=b-a; b=b^(a << 8);
c=c-a; c=c-b; c=c^(b >> 13);
a=a-b; a=a-c; a=a^(c >> 12);
b=b-c; b=b-a; b=b^(a << 16);
c=c-a; c=c-b; c=c^(b >> 5);
a=a-b; a=a-c; a=a^(c >> 3);
b=b-c; b=b-a; b=b^(a << 10);
c=c-a; c=c-b; c=c^(b >> 15);
return c;
}
The best answer is to use <random>. If you are using a pre C++11 version, you can look at the Boost random number stuff.
But if we are talking about rand() and srand()
The best simplest way is just to use time():
int main()
{
srand(time(nullptr));
...
}
Be sure to do this at the beginning of your program, and not every time you call rand()!
Side Note:
NOTE: There is a discussion in the comments below about this being insecure (which is true, but ultimately not relevant (read on)). So an alternative is to seed from the random device /dev/random (or some other secure real(er) random number generator). BUT: Don't let this lull you into a false sense of security. This is rand() we are using. Even if you seed it with a brilliantly generated seed it is still predictable (if you have any value you can predict the full sequence of next values). This is only useful for generating "pseudo" random values.
If you want "secure" you should probably be using <random> (Though I would do some more reading on a security informed site). See the answer below as a starting point: https://stackoverflow.com/a/29190957/14065 for a better answer.
Secondary note: Using the random device actually solves the issues with starting multiple copies per second better than my original suggestion below (just not the security issue).
Back to the original story:
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.
int main()
{
struct timeval time;
gettimeofday(&time,NULL);
// microsecond has 1 000 000
// Assuming you did not need quite that accuracy
// Also do not assume the system clock has that accuracy.
srand((time.tv_sec * 1000) + (time.tv_usec / 1000));
// The trouble here is that the seed will repeat every
// 24 days or so.
// If you use 100 (rather than 1000) the seed repeats every 248 days.
// Do not make the MISTAKE of using just the tv_usec
// This will mean your seed repeats every second.
}
if you need a better random number generator, don't use the libc rand. Instead just use something like /dev/random or /dev/urandom directly (read in an int directly from it or something like that).
The only real benefit of the libc rand is that given a seed, it is predictable which helps with debugging.
On windows:
srand(GetTickCount());
provides a better seed than time() since its in milliseconds.
C++11 random_device
If you need reasonable quality then you should not be using rand() in the first place; you should use the <random> library. It provides lots of great functionality like a variety of engines for different quality/size/performance trade-offs, re-entrancy, and pre-defined distributions so you don't end up getting them wrong. It may even provide easy access to non-deterministic random data, (e.g., /dev/random), depending on your implementation.
#include <random>
#include <iostream>
int main() {
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);
std::uniform_int_distribution<> dist{1,100};
for (int i=0; i<50; ++i)
std::cout << dist(eng) << '\n';
}
eng is a source of randomness, here a built-in implementation of mersenne twister. We seed it using random_device, which in any decent implementation will be a non-determanistic RNG, and seed_seq to combine more than 32-bits of random data. For example in libc++ random_device accesses /dev/urandom by default (though you can give it another file to access instead).
Next we create a distribution such that, given a source of randomness, repeated calls to the distribution will produce a uniform distribution of ints from 1 to 100. Then we proceed to using the distribution repeatedly and printing the results.
Best way is to use another pseudorandom number generator.
Mersenne twister (and Wichmann-Hill) is my recommendation.
http://en.wikipedia.org/wiki/Mersenne_twister
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 ).
The real question you must ask yourself is what randomness quality you need.
libc random is a LCG
The quality of randomness will be low whatever input you provide srand with.
If you simply need to make sure that different instances will have different initializations, you can mix process id (getpid), thread id and a timer. Mix the results with xor. Entropy should be sufficient for most applications.
Example :
struct timeb tp;
ftime(&tp);
srand(static_cast<unsigned int>(getpid()) ^
static_cast<unsigned int>(pthread_self()) ^
static_cast<unsigned int >(tp.millitm));
For better random quality, use /dev/urandom. You can make the above code portable in using boost::thread and boost::date_time.
The c++11 version of the top voted post by Jonathan Wright:
#include <ctime>
#include <random>
#include <thread>
...
const auto time_seed = static_cast<size_t>(std::time(0));
const auto clock_seed = static_cast<size_t>(std::clock());
const size_t pid_seed =
std::hash<std::thread::id>()(std::this_thread::get_id());
std::seed_seq seed_value { time_seed, clock_seed, pid_seed };
...
// E.g seeding an engine with the above seed.
std::mt19937 gen;
gen.seed(seed_value);
#include <stdio.h>
#include <sys/time.h>
main()
{
struct timeval tv;
gettimeofday(&tv,NULL);
printf("%d\n", tv.tv_usec);
return 0;
}
tv.tv_usec is in microseconds. This should be acceptable seed.
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 for srand, use just an int of them, as such:
#include <sys/auxv.h>
void initrand(void)
{
unsigned int *seed;
seed = (unsigned int *)getauxval(AT_RANDOM);
srand(*seed);
}
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.
Suppose you have a function with a signature like:
int foo(char *p);
An excellent source of entropy for a random seed is a hash of the following:
Full result of clock_gettime (seconds and nanoseconds) without throwing away the low bits - they're the most valuable.
The value of p, cast to uintptr_t.
The address of p, cast to uintptr_t.
At least the third, and possibly also the second, derive entropy from the system's ASLR, if available (the initial stack address, and thus current stack address, is somewhat random).
I would also avoid using rand/srand entirely, both for the sake of not touching global state, and so you can have more control over the PRNG that's used. But the above procedure is a good (and fairly portable) way to get some decent entropy without a lot of work, regardless of what PRNG you use.
For those using Visual Studio here's yet another way:
#include "stdafx.h"
#include <time.h>
#include <windows.h>
const __int64 DELTA_EPOCH_IN_MICROSECS= 11644473600000000;
struct timezone2
{
__int32 tz_minuteswest; /* minutes W of Greenwich */
bool tz_dsttime; /* type of dst correction */
};
struct timeval2 {
__int32 tv_sec; /* seconds */
__int32 tv_usec; /* microseconds */
};
int gettimeofday(struct timeval2 *tv/*in*/, struct timezone2 *tz/*in*/)
{
FILETIME ft;
__int64 tmpres = 0;
TIME_ZONE_INFORMATION tz_winapi;
int rez = 0;
ZeroMemory(&ft, sizeof(ft));
ZeroMemory(&tz_winapi, sizeof(tz_winapi));
GetSystemTimeAsFileTime(&ft);
tmpres = ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (__int32)(tmpres * 0.000001);
tv->tv_usec = (tmpres % 1000000);
//_tzset(),don't work properly, so we use GetTimeZoneInformation
rez = GetTimeZoneInformation(&tz_winapi);
tz->tz_dsttime = (rez == 2) ? true : false;
tz->tz_minuteswest = tz_winapi.Bias + ((rez == 2) ? tz_winapi.DaylightBias : 0);
return 0;
}
int main(int argc, char** argv) {
struct timeval2 tv;
struct timezone2 tz;
ZeroMemory(&tv, sizeof(tv));
ZeroMemory(&tz, sizeof(tz));
gettimeofday(&tv, &tz);
unsigned long seed = tv.tv_sec ^ (tv.tv_usec << 12);
srand(seed);
}
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.
Assuming that the randomness of srand() + rand() is enough for your purposes, the trick is in selecting the best seed for srand. time(NULL) is a good starting point, but you'll run into problems if you start more than one instance of the program within the same second. Adding the pid (process id) is an improvement as different instances will get different pids. I would multiply the pid by a factor to spread them more.
But let's say you are using this for some embedded device and you have several in the same network. If they are all powered at once and you are launching the several instances of your program automatically at boot time, they may still get the same time and pid and all the devices will generate the same sequence of "random" numbers. In that case, you may want to add some unique identifier of each device (like the CPU serial number).
The proposed initialization would then be:
srand(time(NULL) + 1000 * getpid() + (uint) getCpuSerialNumber());
In a Linux machine (at least in the Raspberry Pi where I tested this), you can implement the following function to get the CPU Serial Number:
// Gets the CPU Serial Number as a 64 bit unsigned int. Returns 0 if not found.
uint64_t getCpuSerialNumber() {
FILE *f = fopen("/proc/cpuinfo", "r");
if (!f) {
return 0;
}
char line[256];
uint64_t serial = 0;
while (fgets(line, 256, f)) {
if (strncmp(line, "Serial", 6) == 0) {
serial = strtoull(strchr(line, ':') + 2, NULL, 16);
}
}
fclose(f);
return serial;
}
Include the header at the top of your program, and write:
srand(time(NULL));
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:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//Initialize srand
srand(time(NULL));
//Create random number
int n = rand() % 10 + 1;
//Print the number
cout << n << endl; //End the line
//The main function is an int, so it must return a value
return 0;
}