srand function in C - c

I am trying to code a random number generation function in embedded C where I can't include the math.h file. Thats why I'm not able to use the seed srand function.
Is there any other way to seed it other than time?

Consider using the Mersenne Twister, sources are e.g. here -- much higher quality than traditional linear congruential generators, superbly long period, deeply studied in, and blessed by, plenty of recent academic literature.

srand is in stdlib.h, not math.h. To seed with time you include time.h to use time(NULL), not math.h. I don't see how it's relevant.
If rand and srand are not available, you can create one your own, e.g. LCG or Mersenne twister.
If speed and security is not a concern, you can store the current PRNG state in persistent memory and restart from that point when a random number is required. For instance, MT19937 has period of 219937 - 1 which should be enough for normal purpose when without reseeding.
If seeding is really required, anything that is not constant in any scales can be used as the seed.

Consider having a looksee through this lecture, might give you some ideas (and code).
The pdf goes through a few different options, and even gives a bit of code.

I am trying to code a random number generation function in embedded C where I can't include the math.h file. Thats why I'm not able to use the seed srand function.
srand() is commonly seeded using time(), and that is defined in <time.h>, not in <math.h>.
Is there any other way to seed it other than time?
Of course, you can seed it with anything you want. It depends on your platform what is available.

Related

Is it acceptable to use rand() for cryptographically insecure random numbers?

Is it acceptable to use the C standard library's rand() function for random numbers that do not have to be cryptographically secure? If so, are there still better choices? If not, what should be used?
Of course, I assume the usual caveats about skew apply.
rand() suffers from some serious drawbacks.
There is no guarantee on the quality of the random number. This will vary from implementation to implementation.
The shared state used by different calls to rand, is not guaranteed to be thread safe.
As for POSIX C alternatives, there is random and random_r. OpenSSL provides more advances ways of generating random numbers.
The C++ (C++11 and later) library also provides a number of random number functions if including C++ in your project is an option.
Cryptographic security aside, there are a lot of systems where rand() has pretty atrocious randomness properties, and the standard advice if you need something better is to use the non-Standard random().
rand's poor properties on many systems include:
nonrandomness in the low-order bits (such that e.g. rand()%2 is guaranteed to alternate 0,1,0,1...).
relatively short period, perhaps "only" 4 billion or so
So my (reluctant) advice is that if you need "good" randomness (say, for a Monte Carlo simulation), you may very well want to investigate using a nonstandard alternative to rand(). (One of my eternal questions about C is why any vendor would spend time deploying a nonstandard random() instead of simply making rand() better. And I do know the canonical answers, although they suck.)
See also this similar question.
Yes, it is fine to use rand() to get pseudo-random numbers. In fact, that is the whole point of rand(). For simple tasks, where it is OK to be deterministic, you can even seed the system clock for simplicity.
The implementation of rand in mainstream C standard libraries may be adequate for casual use of pseudorandom numbers (such as in most single-player games, or for aesthetic purposes), especially if your application doesn't care about repeatable "randomness" across time or across computers. (But note that the rand specification in the C standard doesn't specify a particular distribution that the numbers delivered by rand have to follow.)
However, for more serious use of pseudorandom numbers, such as in a scientific simulation, I refer you to another answer of mine, where I explain that the problem with rand/srand is that rand—
Uses an unspecified RNG algorithm, yet
allows that RNG to be initialized with srand for repeatable "randomness".
These two points, taken together, hamper the ability of implementations to improve on the RNG's implementation; changing that RNG will defeat the goal of repeatable "randomness", especially if an application upgrades to a newer version of the C runtime library by the same vendor or is compiled with library implementations by different vendors. The first point also means that no particular quality of pseudorandom numbers is guaranteed. Another problem is that srand allows for only relatively small seeds — namely those with the same size as an unsigned.
However, even if the application doesn't care about repeatable "randomness", the fact that rand specifies that it behaves by default as though srand(1) were called (and thus, in practice, generates the same pseudorandom sequence by default) makes using rand harder to use effectively than it could be.
A better approach for noncryptographic pseudorandom numbers is to use a PRNG library—
that uses self-contained PRNGs that maintain their own state (e.g., in a single struct) and don't touch global state, and
that implements a PRNG algorithm whose details are known to the application.
I list several examples of high-quality PRNG algorithms for noncryptographic pseudorandom numbers.

using the time function for srand in pseudo-random number generator in c

#include <time.h>
((unsigned)time(NULL));
I don't understand why you have to include the time header file and use the time function in your program when creating a pseudo-random number generator using the function srand(). Can somebody please explain what the significance of time is in this case?
* Please note that the code shown is only part of the program. Thank you.
It's because of the Pseudo- part of Pseudorandom. The PRNG performs a mathematical operation upon an internally-stored seed value to yield the next output number and transform the seed.
If you don't call time(NULL) or some other source of entropy (eg. /dev/rand), then the sequence will still be pseudo-random (not easily predictable by examining the values), but it will be exactly the same for every run of the program. Because, even though it may be very difficult to accurately predict the next number, it is possible because the PRNG is deterministic.
If you don't provide your own seed with srand(), the default initial seed is usually 1.
The time() call provides the initial source of entropy that makes the starting seed unpredictable.
It makes the code non-repeatable when it is called for a second time. If you include no seed or a fixed number for a seed, the program will act exactly the same, because the random number will be the same.

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).

trying to find a fully-random number generator

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

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