trying to find a fully-random number generator - c

I work in C and i am trying(desperately) to make a random generator that not only generates
a different number every time i run the generator but also a different sequence every time i run the program.I tested almost everything i found online.I resulted in 2 good ways to make a good random generator.
The first one is to use a different seed every time.But this means that i have to use a different-random seed every time,a matter that i didn't solve at first.Here is what i am trying now but it's not truly random as i want:
int myrand(int random_seed){
random_seed = random_seed * 1103515245 +12345;
return (unsigned int)(random_seed / 65536) % 32768;
}
Every time i call the function i increase the seed by 1.
The second way is to use time.Time changes and this is randomness.I also tried many ways to implement this.My latest try is here:
Compiler error-Possible IDE error"undefined reference to gettimeofday error"
but i couldn't use the gettimeofday function because i work in Windows.Also in that question i didn't get any answers.
Could anyone give help me of how i can implement a random generator(probably using time) in C working in Windows?Or should i use Unix?

Seed your RNG with a good source of entropy.
Under unix, use /dev/random.
Under windows, use something like CryptoAPI - Windows equivalent of /dev/random

What you are asking for is not a random number generator, but how to use the random number generator already included in the C standard library.
All you need to do is seed it once at program startup:
srand(time(NULL));
That's all. It's portable and will give you a different sequence every time you run the program, given that at least one second has passed since the last time you've ran it.
There is no harm in seeding it again later, but no point in it either.

The C standard library has the header time.h (or ctime if you are using C++)(reference). The functions there will be supported in Windows and Unix.
I would recommend time() or clock() as seed for your random number generator.
An other way to get totally random input is the usage of the mouse position or other things influenced from outside.

There are many ways to implement prng but unfortunately none of them is real random number generator. time(NULL) is a good approach but I'm using "blum blum shub". It generates one bit random number

Since you're asking explicitly for a Windows solution I'd suggest to avoid time(NULL) or clock() as a seed for srand()since their granularity is very limited (ms). Instead you could use the result of the performance counter:
LARGE_INTEGER PerformanceCount;
QueryPerformanceCounter(&PerformanceCount);
srand(PerformanceCount.LowPart);
The increment rate of the frequency of QueryPerformanceCounter() can be obtained by a call to QueryPerformanceFrequency(). This typically increases at at least 1 MHz and sometimes even into the GHz range. Therefore it provides a fast changing source for the seed.
Edit: As understood from your earlier question also a gettimeofday() alike implementation won't give fine granularity. It may show the word tv_usec in its argument but on WIndows it will not provide microseconds granularity as it does on Linux systems.

quote:
to make a random generator that not only generates a different number every time i run the generator
Definitions of random do not include that concept. Rather the idea is that you have an equal chance of selecting any number, regardless of the number previously chosen. Which means it is theoretically possible to pick the same number twice.
If you are dealing a deck of cards then that meets your criterion of no duplicates. Using the deck dealing approach means keeping track of "used" numbers.
You should also be aware that PNRGs (pseudorandom number generators) are cyclic (periodic). After you have generated numbers, usually a large number, you then start all over again and repeat exactly the name sequence of numbers. The UNIX rand() function generates integers integers in the range [0, {RAND_MAX}] and has a period of 2^32
Really consider reading this short page:
See: http://pubs.opengroup.org/onlinepubs/009695399/functions/rand.html

Related

How to generate either 0 or 1 randomly in C

I have read so many posts on this topic:
How does rand() work? Does it have certain tendencies? Is there something better to use?
How does the random number generator work in C
and this is what I got:
1) xn+1 depends on xn i.e., previous random number that is generated.
2) It is not recommended to initialize the seed more than once in the program.
3) It is a bad practice to use rand()%2 to generate either 0 or 1 randomly.
My questions are:
1) Are there any other libraries that I missed to take a look to generate a completely random number (either 0 or 1) without depending on previous output?
2) If there is any other work around using the inbuilt rand() function to satisfy the requirement?
3) What is the side effect of initializing the seed more than once in a program?
Code snippet:
srand(time(NULL));
d1=rand()%2;
d2=rand()%2;
Here my intention is to make d1 and d2 completely independent of each other.
My initial thought is to do this:
srand(time(NULL));
d1=rand()%2;
srand(time(NULL));
d2=rand()%2;
But as I mentioned earlier which is based on other posts, this is a bad practice I suppose?
So, can anyone please answer the above questions? I apologize if I completely missed an obvious thing.
Are there any other libraries that I missed to take a look to generate a completely random number between 0 and 1 without depending on previous output?
Not in the standard C library. There are lots of other libraries which generate "better" pseudo-random numbers.
If there is any other work around using the inbuilt rand() function to satisfy the requirement?
Most standard library implementations of rand produce sequences of random numbers where the low-order bit(s) have a short sequence and/or are not as independent of each other as one would like. The high-order bits are generally better distributed. So a better way of using the standard library rand function to generate a random single bit (0 or 1) is:
(rand() > RAND_MAX / 2)
or use an interior bit:
(rand() & 0x400U != 0)
Those will produce reasonably uncorrelated sequences with most standard library rand implementations, and impose no more computational overhead than checking the low-order bit. If that's not good enough for you, you'll probably want to research other pseudo-random number generators.
All of these (including rand() % 2) assume that RAND_MAX is odd, which is almost always the case. (If RAND_MAX were even, there would be an odd number of possible values and any way of dividing an odd number of possible values into two camps must be slightly biased.)
What is the side effect of initializing the seed more than once in a program?
You should think of the random number generator as producing "not very random" numbers after being seeded, with the quality improving as you successively generate new random numbers. And remember that if you seed the random number generator using some seed, you will get exactly the same sequence as you will the next time you seed the generator with the same seed. (Since time() returns a number of seconds, two successive calls in quick succession will usually produce exactly the same number, or very occasionally two consecutive numbers. But definitely not two random uncorrelated numbers.)
So the side effect of reseeding is that you get less random numbers, and possibly exactly the same ones as you got the last time you reseeded.
1) Are there any other libraries that I missed to take a look to
generate a completely random number between 0 and 1 without depending
on previous output?
This sub-question is off-topic for Stack Overflow, but I'll point out that POSIX and BSD systems have an alternative random number generator function named random() that you could consider if you are programming for such a platform (e.g. Linux, OS X).
2) If there is any other work around using the inbuilt rand() function
to satisfy the requirement?
Traditional computers (as opposed to quantum computers) are deterministic machines. They cannot do true randomness. Every completely programmatic "random number generator" is in practice a psuedo-random number generator. They generate completely deterministic sequences, but the values from a given set of calls are distributed across the generator's range in a manner approximately consistent with a target probability distribution (ordinarily the uniform distribution).
Some operating systems provide support for generating numbers that depend on something more chaotic and less predictable than a computed sequence. For instance, they may collect information from mouse movements, CPU temperature variations, or other such sources, to produce more objectively random (yet still deterministic) numbers. Linux, for example, has such a driver that is often exposed as the special file /dev/random. The problem with these is that they have a limited store of entropy, and therefore cannot provide numbers at a sustained high rate. If you need only a few random numbers, however, then that might be a suitable source.
3) What is the side effect of initializing the seed more than once in
a program?
Code snippet:
srand(time(NULL));
d1=rand()%2;
d2=rand()%2;
Here my intention is to make d1 and d2 completely independent of each
other.
My initial thought is to do this:
srand(time(NULL));
d1=rand()%2;
srand(time(NULL));
d2=rand()%2;
But as I mentioned earlier which is based on other posts, this is a
bad practice I suppose?
It is indeed bad if you want d1 and d2 to have a 50% probability of being different. time() returns the number of seconds since the epoch, so it is highly likely that it will return the same value when called twice so close together. The sequence of pseudorandom numbers is completely determined by the seed (this is a feature, not a bug), and when you seed the PRNG, you restart the sequence. Even if you used a higher-resolution clock to make the seeds more likely to differ, you don't escape correlation this way; you just change the function generating numbers for you. And the result does not have the same guarantees for output distribution.
Additionally, when you do rand() % 2 you use only one bit of the approximately log2(RAND_MAX) + 1 bits that it produced for you. Over the whole period of the PRNG, you can expect that bit to take each value the same number of times, but over narrow ranges you may sometimes see some correlation.
In the end, your requirement for your two random numbers to be completely independent of one another is probably way overkill. It is generally sufficient for the pseudo-random result of one call to be have no apparent correlation with the results of previous calls. You probably achieve that well enough with your first code snippet, even despite the use of only one bit per call. If you prefer to use more of the bits, though, then with some care you could base the numbers you choose on the parity of the count of how many bits are set in the values returned by rand().
Use this
(double)rand() / (double)RAND_MAX
completely random number ..... without depending on previous output?
Well in reality computers can't generate completely random numbers. There has to be some dependencies. But for almost all practical purposes, you can use rand().
side effect of initializing the seed more than once
No side effect. But that would mean you're completely invalidating the point of using rand(). If you're re initilizeing seed every time, the random number is more dependent on time(and processor).
any other work around using the inbuilt rand() function
You can write something like this:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(int argc,char *argv[])
{
srand(time(NULL));
printf("%lf\n",(double)rand()/(double)RAND_MAX);
printf("%lf\n",(double)rand()/(double)RAND_MAX);
}
If you want to generate either a 0 or a 1, I think using rand()%2 is perfectly fine as the probability of an even number is same as probability of an odd number(probability of all numbers is equal for an unbiased random number generator).

Random Number In C Independent Of Time

Is there a way to generate random numbers in c language independent of time.
The idea is that I want to generate an array of random numbers at a time,but since rand() method depends on time,all the values in the array are generated similarly.
rand() doesn't depend on time. People typically seed their pseudo-random number generator using the current time (through the srand() function), but they don't have to. You can just pass whatever number you want to srand().
If your random numbers aren't of a high enough quality for your purposes (libc's rand is notorious for its inadequacy), you should look at other sources of randomness. On most operating systems, you can get high-quality random data just by reading from /dev/random (or /dev/urandom), and the Windows API provides CryptGenRandom. There are also a lot of cross-platform libraries that provide high-quality PRNGS; OpenSSL is one of them.
rand() generates values sequentially (in a time-sequence), but does not depend upon time (as in "time of day"), unless you seed the generator with srand(time(NULL)). If you don't do this, it's dependent on 1 (one).
There's also rand_r() (POSIX) to return the value of the current seed. You could use these to coordinate multiple streams of random-numbers, by saving and restoring the appropriate seed values.
For a non-deterministic seed without using time(NULL) you'll probably have to resort to a system-specific source (/dev/random on unix).
At all costs don't do this, and proceed to use myrand() as a replacement for rand(). This will return the same value for each call during each clock second.
unsigned myrand() { // BAD! NO!
srand(time(NULL)); // re-seeding destroys the properties of `rand()`
return rand();
}
If you call srand(), it should be just once at the beginning of the program.
The sequential determinism of rand() is actually a very useful property for testing programs. What you get is an (almost-)random, but repeatable sequence. If you print out the seed value at the start of the program, you can re-use the same value to produce the same results (like if it doesn't work on that run).

Is there a better function than rand()?

I have a program, in C, which creates an array of 1000 integers using a random number from 0-999 and then performs some sort of algorithm on that array. In order to test the algorithm's running time, I try running the program 10000 times, but every time I run it the array is the same for a few arrays and then it changes. I have used the srand() function to feed the seed with the current time, but it still does not help.
Is there an alternative solution to rand() or a way to fix this?
My function is:
void getarray(int *ptr1, int size, int option){
int n;
srand(time(NULL));
for(n=0; n<size; n++)
*(ptr1+n) = *(ptr2+n)= rand()%1000;
}
Thanks in advance!
You should only call srand once: on program startup.
Right now, if you call your function multiple times before time changes your sequence will be the same.
The lrand48() call tends to have a lot more state internally and a better pseudorandom number distribution.
However, note that you're reseeding with only 1-second granularity, so calls within the same second will generate the same sequence. Put your srand() call in main() or somewhere, once, instead of recalling it in getarray.
You should investigate very carefully if rand() is the better function for the job.
It varies by compiler and platforms but it is often implmented as a "Linear congruential generator" which are very convenient in terms of speed and memory usage but have poor statistical properties (i.e. you can tell if a long enough sequence has been generated by congruential random generator or if it's truly random).
In your use case (testing algorithm's speed) may be perfectly fine to use rand() as long the execution is not influenced by the statistical properties of the data. If rand() is a linear congruential RNG, number sequences show a pattern which means that at any given time it is not true that all the numbers are equiprobable. A nice example is in this wikipedia picture:
Your system might also have a RNG (e.g. /dev/random) and its associated functions but be aware that those are meant to produce few high quality random numbers and may be pretty slow to use. You might even run out of numbers and end up waiting for the system to collect more enthropy!
A simple, pretty fast RNG with statistical properties good enough for cryptography is ISAAC. Personally I use it whenever I need decent random numbers.
Another alternative is to use true random numbers as those generated by RANDOM.org or HotBits but it may be overkill in your case.
As a side note, RANDOM.ORG has a nice page on RNG with another example of "patterns" created by the PHP rand() function
First, call the seed function once, not in a loop.
Second, I suggest you either :
1) Switch to the random(3) function
2) Pick something from rand48 / lrand48
3) Read the number of desired bytes for /dev/random yourself.
Solution 1) is easy and somewhat portable. 2 need a bit of thinking, 3 is the most work, and the least portable.

What is the best way to seed srand()? [duplicate]

This question already has answers here:
Recommended way to initialize srand?
(15 answers)
Closed 9 years ago.
The way I learned was to initially seed the random number generator with srand(time(NULL)) and then use calls to rand() to generate random numbers. The problem with this approach is if I run my program multiple times in the same second, the random numbers generated will always be the same. What is a good way around this?
On POSIX systems, use clock_gettime to get the current time in nanoseconds. If you don't need a lot of bits, you can just forget the PRNG and use the low-order bits of the time as your random number directly. :-)
int pid ; // get it as per your OS
timeval t;
gettimeofday(&t, NULL);
srand(t.tv_usec * t.tv_sec * pid);
time gives you values based on second. gettimeofday is based on microseconds. So less chance of the same seed happening. Plus you are also using the process id.
If *nix, Why don't you read directly from /dev/random?
Also you can gather noise from other devices, like the keyboard, mouse or the CPU temperature.
You can use an accelerometer and use it to gather noise from sea waves. The Wind also produce noise.
I believe Glib provides a function, g_random_int() which produces random numbers equally distributed in a fast and portable way.
Or you can just read the numbers of temporal files in /tmp and use that number to feed srand() with a time.h function, or read the content of one file in /tmp.
You can read each file from /usr/bin or / and gather some food for srand().
Besides using time, another common way to seed your rand function is to use the process id of your program, since that is guaranteed to be unique.
The actual code is platform-dependent, but if you're on Windows, I believe you can use the function GetCurrentProcessId(), as in
srand(GetCurrentProcessId());
Beside inputting the time, you could add the CPU time to this, which I believe can be do with clock().
So it would look like this: srand(time() + clock()).

How to 'randomize()' random numbers in C(Linux)?

Trying to generate random numbers in C, rand() doesn't generate different numbers each time i compile the code, can anyone tell me how to use srand() or tell any other method for generating.
In order to generate a sequence of pseudorandom numbers, the generator needs to be seeded. The seed fully determines the sequence of numbers that will be produced. In C, you seed with srand, as you indicate. According to the srand(3) man page, no explicit seeding implies that the generator will use 1 as a seed. This expains why you always see the same numbers (but do remember that the sequence itself is pretty random, with quality depending on the generator used, even though the sequence is the same each time).
User mzabsky points out that one way to get a seed that feels random to a human user is to seed with time. Another common method (which I just saw that mzabsky also points out - sorry) is to seed the generator with the contents of the system's random number generator, which draws from an entropy pool fed by things such as mouse movement, disk timings etc. You can't draw a lot of randomness from the system generator, as it won't be able to gather enough entropy. But if you just draw a seed from it, you'll have chosen at random a sequence of random numbers in your program. Here's an example of how to do that in C on Linux:
unsigned int seed;
FILE* urandom = fopen("/dev/urandom", "r");
fread(&seed, sizeof(int), 1, urandom);
fclose(urandom);
srand(seed);
In light of Conrad Meyer's answer, I thought I'd elaborate a bit more. I'd divide the use of random numbers into three categories:
Variation. If you use random numbers to create seemingly random or varied behavior in for example a game, you don't need to think very hard about the topic, or about choosing a proper seed. Seed with time, and look at some other solution if this turns out not to be good enough. Even relatively bad RNGs will look random enough in this scenario.
Scientific simulations. If you use random numbers for scientific work, such as Monte Carlo calculations, you need to take care to choose a good generator. Your seed should be fixed (or user-changeable). You don't want variation (in the sense above); you want deterministic behavior but good randomness.
Cryptography. You'll want to be extremely careful. This is probably out of the scope of this thread.
This is commonly used solution:
srand ( time(NULL) );
Execution of all C code is deterministic, so you have to bring in something that is different every time you call the srand. In this case it is time.
Or you can read data from /dev/random (open it just like any other file).
If you are using an OS that does not provide /dev/random then use something like what is shown below
timeval t1;
gettimeofday(&t1, NULL);
srand(t1.tv_usec * t1.tv_sec);
This piece of code can be ported easily to other OS.
To improve the seed- you can combine (maybe using MD5 or a checksum algorithm) time product shown above with a MAC address of the host machine.
timeval t1;
gettimeofday(&t1, NULL);
unsigned int seed = t1.tv_usec * t1.tv_sec;
unsigned char mac_addr[6];
getMAC(&mac_addr);
improveSeedWithMAC(&seed, mac_addr) ; // MD5 or checksum ...
srand(seed);
Be careful; the rand(3) manpage on linux notes that rand() implementations on some platforms do not give good randomness on the lower-order bits. For this reason, you might want to use a library to acquire real random numbers. Glib provides useful functions like g_random_int_range() which may better suite your purpose.

Resources