5

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?

Community
  • 1
  • 1
Dchris
  • 2,867
  • 10
  • 42
  • 73
  • 2
    Is something wrong with `srand()`? You can seed it will the time like this: `srand( time(NULL) );` – Hunter McMillen Dec 18 '12 at 17:42
  • i also tried srand(time(NULL)) but i had to make delays in order to wait the time to change.The reason is that i want to generate a big amount of random numbers in once and i don't want to wait 2 minutes for the program to generate them.I also tried to use milliseconds but with no success.Maybe milliseconds is the answer but i could't implement it correct,again the problem was that i am using windows. – Dchris Dec 18 '12 at 17:56
  • 2
    @Dchris: seed your pseudo-random number generator (PRNG) with the time *once*, at the start of the program. Then you might have to make sure not to run your program more than once per second (and introducing milliseconds would help with that), but you don't have to wait one second for each time you read a number from your PRNG. – Steve Jessop Dec 18 '12 at 17:58
  • @SteveJessop: i hope this is going to work! – Dchris Dec 18 '12 at 18:49

6 Answers6

4

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

Community
  • 1
  • 1
evil otto
  • 10,348
  • 25
  • 38
  • 1
    This is for important randomness only. Reading from /dev/random will drain the system of entropy, which will result in blocking when it's finally empty, until the system has gathered more entropy. Of course the OP didn't state whether or not the problem he's trying to solve is security related or not. I suspect it's not. – Nikos C. Dec 18 '12 at 17:48
  • changed to note that you can just seed the rng that way. – evil otto Dec 18 '12 at 17:52
  • 1
    On C++11 you can use [`std::random_device`](http://en.cppreference.com/w/cpp/numeric/random/random_device) which will presumably use whatever source of truly random data is on the system. –  Dec 22 '12 at 16:27
3

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.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
  • Reseeding should not be taken lightly. Depending on the PRNG algorithm reseeding may be desirable to increase entropy but there are definitely right and wrong ways to reseed and cryptographics attacks based on poor reseeding. As you've said reseeding for simple PRNG use-cases is usually not neccesary. For example the MT algorithm can generate an astonishing 2^19937−1 numbers before it repeats itself. Other ones are good to 2^32 numbers before cycling. – bot403 Dec 18 '12 at 20:00
1

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.

Johannes Jendersie
  • 980
  • 10
  • 16
0

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

Polymorphism
  • 249
  • 1
  • 9
0

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.

Community
  • 1
  • 1
Arno
  • 4,994
  • 3
  • 39
  • 63
0

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

jim mcnamara
  • 16,005
  • 2
  • 34
  • 51