Generate random long number - c++

I know that to generate random long number, I do following steps in Java:
Random r = new Random();
return r.nextLong();
What will be equivalent of this code in C++? like this?
return (long)rand();

<cstdlib> provides int rand(). You might want to check out the man page. If long is bigger than int on your system, you can call rand() twice and put the first value in the high word.
#include <cstdlib>
long lrand()
{
if (sizeof(int) < sizeof(long))
return (static_cast<long>(rand()) << (sizeof(int) * 8)) |
rand();
return rand();
}
(it's very unlikely that long is neither the same as or double the size of int, so this is practical if not theoretically perfect)
Check your docs for rand() though. It's not a great generator, but good enough for most things. You'll want to call srand() to initialise the random-number generation system. Others have commented that Windows doesn't return sizeof(int) randomised bits, so you may need to tweak the above.

Using boost random library can save you of quite nasty surprises with (pseudo)random numbers

First, you have ton know that in the current standard C++ there is no random library. In fact there is one, but it's available in a sperate namespace called TR1 because it's the result of a Technical Report done in 2003. It will be available in the standard library for the next standard (coming next year if all goes well).
So if you have a recent compiler (VS2008 or lasts versions of GCC) you have access to the std::tr1::random library; If you have a compiler implementing the parts of the next standard, then you have it std::random.
If you don't have access to that library, there is an implementation available in the boost libraries : http://www.boost.org/doc/libs/1_44_0/doc/html/boost_random.html
Now in all cases, the way to get a random number is the same as it's all the same library (from the boost doc):
boost::mt19937 rng; // produces randomness out of thin air
// see pseudo-random number generators
boost::uniform_int<> six(1,6); // distribution that maps to 1..6
// see random number distributions
boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
die(rng, six); // glues randomness with mapping
int x = die(); // simulate rolling a die

C++11 provides the <random> library. To generate a long, you would use code like:
#include <random>
#include <climits>
...
std::default_random_engine generator;
std::uniform_int_distribution<long> distribution(LONG_MIN,LONG_MAX);
long result = distribution(generator);

Portable hack:
long r = 0;
for (int i = 0; i < sizeof(long)/sizeof(int); i++)
{
r = r << (sizeof(int) * CHAR_BITS);
r |= rand();
}
return r;
Why do you need a random long anyway?

This is the method I use. It is returning numbers in range [0, 2^64-1].
unsigned long long unsignedLongLongRand()
{
unsigned long long rand1 = abs(rand());
unsigned long long rand2 = abs(rand());
rand1 = rand1 << (sizeof(int)*8);
unsigned long long randULL = (rand1 | rand2);
return randULL;
}

this function works like rand() and uses Unsigned Long Type:
unsigned long _LongRand ()
{
unsigned char MyBytes[4];
unsigned long MyNumber = 0;
unsigned char * ptr = (unsigned char *) &MyNumber;
MyBytes[0] = rand() % 256; //0-255
MyBytes[1] = rand() % 256; //256 - 65535
MyBytes[2] = rand() % 256; //65535 -
MyBytes[3] = rand() % 256; //16777216
memcpy (ptr+0, &MyBytes[0], 1);
memcpy (ptr+1, &MyBytes[1], 1);
memcpy (ptr+2, &MyBytes[2], 1);
memcpy (ptr+3, &MyBytes[3], 1);
return(MyNumber);
}

Related

how to generate the same random number in two different environments?

I compiled exactly the same code that generate random numbers in two different environments ( Linux and visual studio ). But I noticed that the outputs are different. I searched online and understand that the two implementations generate different random numbers. But I need the Linux to generate the same random numbers of that generated by visual studio.
So, how to let the two different environments ( Linux and visual studio ) generate the same random numbers. Any ideas.
My code:
void mix_dataset(array<array<int, 20>, 5430>& array_X_dataset, array<int, 5430>& array_Y_dataset) {
// size_t len = array_X_dataset.size();
// for (size_t i = 0; i < len; ++i) {
// size_t swap_index = rand() % len;
mt19937 engine;
engine.seed(3);
for (size_t i = 0; i < 5430; ++i) {
size_t swap_index = engine() % 5430;
if (i == swap_index)
continue;
array<int, 20> data_point{ };
data_point = array_X_dataset[i];
array_X_dataset[i] = array_X_dataset[swap_index];
array_X_dataset[swap_index] = data_point;
int Y = array_Y_dataset[i];
array_Y_dataset[i] = array_Y_dataset[swap_index];
array_Y_dataset[swap_index] = Y;
}
}
int main(){
srand(3);
mix_dataset(array_X_dataset, array_Y_dataset);
}
You can use a the mersenne twister it has reproducable output (it is standardized).
Use the same seed on 2 machines and you're good to go.
#include <random>
#include <iostream>
int main()
{
std::mt19937 engine;
engine.seed(1);
for (std::size_t n = 0; n < 10; ++n)
{
std::cout << engine() << std::endl;
}
}
You can verify it here, https://godbolt.org/z/j5r6ToGY7, just select different compilers and check the output
If you want a pseudorandom number with a known algorithm, you must choose them both explicitly with the C++ library.
You can't do this with rand(), because it will vary between C library implementations.
And please distinguish between pseudorandom number generators (which will produce the same sequence from the same seed) and random ones, which are vanishingly unlikely to coincide.
Since the standard library function implementations offered by the two platforms differ, you'll need to decide on a PRNG that whose output given the same seed is the same on both platforms.
Standard C provides very little in the way of guarantees when it comes to the quality of the PRNG exposed by rand anyway and serious applications should stay away from that.
Whatever the critiques, you would be in a better position using PCG, for example, since you do not seem to need cryptographic quality.
In addition, avoid
size_t swap_index = rand() % len;
as randomness may suffer. You can instead use rejection sampling if the library you choose does not offer an alternative.

C++ Get random number from 0 to max long long integer

I have the following function:
typedef unsigned long long int UINT64;
UINT64 getRandom(const UINT64 &begin = 0, const UINT64 &end = 100) {
return begin >= end ? 0 : begin + (UINT64) ((end - begin)*rand()/(double)RAND_MAX);
};
Whenever I call
getRandom(0, ULLONG_MAX);
or
getRandom(0, LLONG_MAX);
I always get the same value 562967133814800. How can I fix this problem?
What is rand()?
According to this the rand() function returns a value in the range [0,RAND_MAX].
What is RAND_MAX?
According to this, RAND_MAX is "an integral constant expression whose value is the maximum value returned by the rand function. This value is library-dependent, but is guaranteed to be at least 32767 on any standard library implementation."
Precision Is An Issue
You take rand()/(double)RAND_MAX, but you have perhaps only 32767 discrete values to work with. Thus, although you have big numbers, you don't really have more numbers. That could be an issue.
Seeding May Be An Issue
Also, you don't talk about how you are calling the function. Do you run the program once with LLONG_MAX and another time with ULLONG_MAX? In that case, the behaviour you are seeing is because you are implicitly using the same random seed each time. Put another way, each time you run the program it will generate the exact same sequence of random numbers.
How can I seed?
You can use the srand() function like so:
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
int main (){
srand (time(NULL));
//The rest of your program goes here
}
Now you will get a new sequence of random numbers each time you run your program.
Overflow Is An Issue
Consider this part ((end - begin)*rand()/(double)RAND_MAX).
What is (end-begin)? It is LLONG_MAX or ULLONG_MAX these are, by definition, the largest possible values those data types can hold. Therefore, it would be bad to multiply them by anything. Yet you do! You multiply them by rand(), which is non-zero. This will cause an overflow. But we can fix that...
Order of Operations Is An Issue
You then divide them by RAND_MAX. I think you've got your order of operations wrong here. You really meant to say:
((end - begin) * (rand()/(double)RAND_MAX) )
Note the new parantheses! (rand()/(double)RAND_MAX)
Now you are multiplying an integer by a fraction, so you are guaranteed not to overflow. But that introduces a new problem...
Promotion Is An Issue
But there's an even deeper problem. You divide an int by a double. When you do that the int is promoted to a double. A double is a floating-point number which basically means that it sacrifices precision in order to have a big range. That's probably what's biting you. As you get to bigger and bigger numbers both your ullong and your llong end up getting cast to the same value. This could be especially true if you overflowed your data type first (see above).
Uh oh
So, basically, everything about the PRNG you have presented is wrong.
Perhaps this is why John von Neumann said
Anyone who attempts to generate random numbers by deterministic means
is, of course, living in a state of sin.
And, sometimes, we pay for those sins.
How can I absolve myself?
C++11 provides some nice functionality. You can use it as follows
#include <iostream>
#include <random>
#include <limits>
int main(){
std::random_device rd; //Get a random seed from the OS entropy device, or whatever
std::mt19937_64 eng(rd()); //Use the 64-bit Mersenne Twister 19937 generator
//and seed it with entropy.
//Define the distribution, by default it goes from 0 to MAX(unsigned long long)
//or what have you.
std::uniform_int_distribution<unsigned long long> distr;
//Generate random numbers
for(int n=0; n<40; n++)
std::cout << distr(eng) << ' ';
std::cout << std::endl;
}
(Note that appropriately seeding the generator is difficult. This question addresses that.)
typedef unsigned long long int UINT64;
UINT64 getRandom(UINT64 const& min = 0, UINT64 const& max = 0)
{
return (((UINT64)(unsigned int)rand() << 32) + (UINT64)(unsigned int)rand()) % (max - min) + min;
}
Using shift operation is unsafe since unsigned long long might be less than 64 bits on some machines. You can use unsigned __int64 instead, but keep in mind it's compiler dependant, therefore is available only in certain compilers.
unsigned __int64 getRandom(unsigned __int64 const& min, unsigned __int64 const& max)
{
return (((unsigned __int64)(unsigned int)rand() << 32) + (unsigned __int64)(unsigned int)rand()) % (max - min) + min;
}
Use your own PRNG that meets your requirements rather than the one provided with rand that seems not to and was never guaranteed to.
Given that ULLONG_MAX and LLONG_MAX are both way bigger than the RAND_MAX value, you will certainly get "less precision than you want".
Other than that, there's 50% chance that your value is below the LLONG_MAX, as it is halfway throuogh the range of 64-bit values.
I would suggest using the Mersenne-Twister from the C++11, which has a 64-bit variant
http://www.cplusplus.com/reference/random/mt19937_64/
That should give you a value that fits in a 64-bit number.
If you "always get the same value", then it's because you haven't seeded the random number generator, using for example srand(time(0)) - you should normally only seed once, because this sets the "sequence". If the seed is very similar, e.g. you run the same program twice in short succession, you will still get the same sequence, because "time" only ticks once a second, and even then, doesn't change that much. There are various other ways to seed a random number, but for most purposes, time(0) is reasonably good.
You are overflowing the computation, in the expression
((end - begin)*rand()/(double)RAND_MAX)
you are telling the compiler to multiply (ULLONG_MAX - 0) * rand() and then divide by RAND_MAX, you should divide by RAND_MAX first, then multiply by rand().
// http://stackoverflow.com/questions/22883840/c-get-random-number-from-0-to-max-long-long-integer
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <limits.h>
using std::cout;
using std::endl;
typedef unsigned long long int UINT64;
UINT64 getRandom(const UINT64 &begin = 0, const UINT64 &end = 100) {
//return begin >= end ? 0 : begin + (UINT64) ((end - begin)*rand()/(double)RAND_MAX);
return begin >= end ? 0 : begin + (UINT64) rand()*((end - begin)/RAND_MAX);
};
int main( int argc, char *argv[] )
{
cout << getRandom(0, ULLONG_MAX) << endl;
cout << getRandom(0, ULLONG_MAX) << endl;
cout << getRandom(0, ULLONG_MAX) << endl;
return 0;
}
See it live in Coliru
union bigRand {
uint64_t ll;
uint32_t ii[2];
};
uint64_t rand64() {
bigRand b;
b.ii[0] = rand();
b.ii[1] = rand();
return b.ll;
}
I am not sure how portable it is. But you could easily modify it depending on how wide RAND_MAX is on the particular platform. As an upside, it is brutally simple. I mean the compiler will likely optimize it to be quite efficient, without extra arithmetic whatsoever. Just the cost of calling rand twice.
The most reasonable solution would be to use C++11's <random>, mt19937_64 would do.
Alternativelly you might try:
return ((double)rand() / ((double)RAND_MAX + 1.0)) * (end - begin + 1) + begin;
to produce numbers in more reasonable way. However note that just like your first attempt, this will still not be producing uniformly distributed numbers (although it might be good enough).
The term (end - begin)*rand() seems produce an overflow. You can alleviate that problem by using (end - begin) * (rand()/(double)RAND_MAX). Using the second way, I get the following results:
15498727792227194880
7275080918072332288
14445630964995612672
14728618955737210880
with the following calls:
std::cout << getRandom(0, ULLONG_MAX) << std::endl;
std::cout << getRandom(0, ULLONG_MAX) << std::endl;
std::cout << getRandom(0, ULLONG_MAX) << std::endl;
std::cout << getRandom(0, ULLONG_MAX) << std::endl;

Exponential number generator sometimes gives "weird" results

I am building a simulation in C++ and I have an exponential generator to make the burst times of the processes.
Usually it returns values as such: 3.14707,1.04998. But frequently 1/10 occasions such numbers turn out: 2.64823e-307
This is the code of the generator (I am using srand ( time(NULL) ); at the beginning of the program):
double exponential(float u)
{
double x,mean;
mean = 10;
// generate a U(0,1) random variate
x = rand();
u = x / RAND_MAX;
return (-mean * log(u));
}
And this is how I assign the values. The while part inside is my effort to get rid of such values but it didn't work:
for (int i = 0; i < nPages; i++)
{
index[i] = i;
arrival[i]= poisson(r);
burst[i]=exponential(u);
while (burst[i]<1 || burst[i]>150)
{
cout<<"P"<<i<<endl;
burst[i]=(burst[i-1]+burst[i+1])/2;
}
}
Why do you use the C library instead of the C++ library ??
std::random_device rd;
std::default_random_engine gen(rd());
std::exponential_distribution<double> dist(lambda);
double x = dist(gen);
If the size of burst is nPages, then
for (int i = 0; i < nPages; i++)
{
//...
burst[i]=(burst[i-1]+burst[i+1])/2;
}
will step outside its bounds, so you are likely to end up with nonsense.
You need to think about what is required at the edges.
As far as the comments about rand go rand considered harmful is worth a watch. In your case taking log of 0 is not sensible.
Using your exponential function copied verbatim, I cannot reproduce the error you describe. Issues with the PRNG cranking out either 0 or RAND_MAX should only show up one time out of RAND_MAX apiece, not 10% of the time. I suspect either a buggy compiler, or that what you have shared is not the actual code that produces the described problem.

Random but predictable number generator? [C++]

Well I don't really know how to search for the thing I'm looking for.
Google gives tons of results, but none which match my criteria.
So I'm asking it here:
Is there any known piece of code that can create a number, that is predictable, looks random, and is based on a 'seed' (in my case it's the unix timestamp) and between a specified range?
I want to be able to create weather forecast in a script for a game I'm coding (but I need the C++ code which I can port, I don't think many people here are familiar with 'PAWN' [a.k.a. SMALL] scripting language? :) ).
The weather id's vary from 0 to ~100, including some deprecated ID's (so my solution would be to make a array holding valid weather ID's so we don't need to worry about those BAD_ID's, let's not make the function too complicated).
I could possibly make such formula but the problem in the past I had was that the weather was changing too fast (like every second, though I lost the code somewhere :/ ) and for now I'm really out of ideas on how I'm going to make such a formula.
Any suggestions are really appreciated too!
Look at the C implementation of the random number generator used by VB6. It's perfect for games because it generates fairly believable random seqeuences but uses a seed and the same seed always generates the same sequence. So in game data files you can save a set of seed values that will give you known (but random-looking) sequences that you can easily reproduce.
Here's an implementation that returns values in a range:
typedef int Int32;
typedef unsigned int UInt32;
class CRnd
{
private:
static const UInt32 INITIAL_VALUE = 0x50000;
static const UInt32 INCREMENT = 0xC39EC3;
static const UInt32 MULTIPLIER = 0x43FD43FD;
private:
UInt32 m_nRnd;
public:
CRnd () { m_nRnd = INITIAL_VALUE; };
CRnd ( IN UInt32 nSeed ) { m_nRnd = nSeed; };
virtual ~CRnd () {};
Int32 Get ( IN Int32 nFrom, IN Int32 nTo )
{
if ( nTo < nFrom ) // nFrom should be less than nTo
{
Int32 nTmp = nTo;
nTo = nFrom;
nFrom = nTmp;
}
else if ( nTo == nFrom )
{
return ( nTo );
}
m_nRnd = ( m_nRnd * MULTIPLIER + INCREMENT ) & 0xFFFFFF;
float fTmp = (float) m_nRnd / (float) 16777216.0;
return ( (Int32) ( ( fTmp * ( nTo - nFrom + 1 ) ) + nFrom ) );
};
void SetSeed ( IN UInt32 nSeed ) { m_nRnd = nSeed; };
UInt32 GetSeed () { return ( m_nRnd ); };
};
Look into srand and rand for starters.
C++11 includes many more advanced algorithms as well, but for basic needs the above two are sufficient.
To keep the numbers within a range of 0 to n, use the % operator.
Obviously a number cannot be both "predictable" and "random" - those are directly contradictory terms.
I'm assuming what you mean is a number that is both deterministic and semirandom.
Luckily for you, this is what pseudorandom number generators (PRNGs) produce: when they are run with a consistent seed, they give you the same output.
So I would recommend setting your seed with srandom, then using random() % MAX_VALUE to get a number between 0 and MAX_VALUE. If you get a "bad value", just go again. Repeat sans reseeding for as many numbers as you like.
If you need a slow changing value you can use a noise function, such as Perlin Noise.
What you really want is a hash function. To limit the range you can use one of the usual tricks (the dirtiest being the remainder operator).
Specifically, you want to hash integers into integers. You can pick up such a function here. I recommend the one titled "Robert Jenkins' 32 bit integer hash function" -- always worked well for me.
You'll end up with something like:
int time_index = 3;
int weather_state = integer_hash_function(time_index) % (MAX_VALUE - MIN_VALUE + 1) + MIN_VALUE
If you want more interesting weather behavior, you can linearly interpolate between time values. You can use Perlin noise with linear combinations of such interpolated noise at differing frequencies and intensities to make some pretty nice behavior. (I've done this with multiplayer RPGs and it works well.)
The problem with srand and rand is that only their call signatures (and not the values they generate) are dictated by the C standard. If you need portable and deterministic pseudo-random numbers, you should implement it yourself. Here is a class, written in C++, which is based on one found in Numerical Recipes, and is completely portable. You may instantiate the random number stream with a seed if you'd like to. I hard-code this seed instead of using the time in case I want the same pseudo-random sequence again and again. You can also use the RandomInteger(a,b) method to get integers on the half-open interval [a,b).
class RandomNumberStream
{
private:
unsigned long long u,v,w;
public:
RandomNumberStream(int n=1);
double RandomDouble();
double RandomDouble(double a, double b);
unsigned long long RandomInteger();
unsigned long long RandomInteger(int a, int b);
private:
unsigned long long int64();
} ;
RandomNumberStream::RandomNumberStream(int n)
{
v = 4101842887655102017LL;
w = 1;
u = n^v; int64();
v = u; int64();
w = v; int64();
}
double RandomNumberStream::RandomDouble()
{
return int64() * 5.42101086242752217E-20f;
}
double RandomNumberStream::RandomDouble(double a, double b)
{
return int64() * 5.42101086242752217E-20f * (b-a) + a;
}
unsigned long long RandomNumberStream::RandomInteger()
{
return int64();
}
unsigned long long RandomNumberStream::RandomInteger(int a, int b)
{
return a + int64() % (b-a);
}
unsigned long long RandomNumberStream::int64()
{
u = u * 2862933555777941757LL + 7046029254386353087LL;
v ^= v>>17; v ^= v<<31; v ^= v>>8;
w = 4294957665U*(w & 0xffffffff) + (w>>32);
unsigned long long x = u^(u<<21); x ^= x>>35; x ^= x<<4;
return (x+v)^w;
}
I think you can use rand for generating random numbers. However, you can give the same value to srand like say 99 so that your numbers will be random but predictable every time.
int iSecret = 0;
/* initialize random seed: */
srand ( 99 );
/* generate secret number: */
iSecret = rand();

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;
}