I had a requirement to have random numbers generated in a C application.

```#include <stdlib.h>
#include <stdio.h>
int main()
{
int i = 0;
for (i = 0; i < 5; i++) {
printf("Random number %d  =  %ld\n", i, random());
}
return 0;
}
```

I ran the code once and saw that random numbers were getting generated.

But to my surprise when I ran the code second time, I saw the same numbers getting printed.

What??? Does it mean random numbers are predictable? If so, why is it called random? `Random` and `Predictable` words literally contradicting each other.

But I remember using random.random() in Python which each time gave different output.

```from random import random
for i in xrange(3):
print random()
```

Each time I executed this code I got different set of output.

Is the random function implementation in libc is so buggy? Of course, cannot be!!!

Oh wait. Are we missing something here.

If there is going to some algorithm for generating random numbers it means that we telling the computer to perform a series of steps and give us a result. If the series of steps is defined it implies that the result is predictable.

They would have added some variable parameter into the equation making it unpredictable. That variable parameter can be anything like - derived from current timestamp or current data in the network device.

If so, does it mean Python implementors thought of this and libc implementors missed it?

When I checked the man page of random() function in my Linux machine. It said,

The random() function uses a nonlinear additive feedback random number generator employing a default table of size 31 long integers to return successive pseudo-random numbers in the range from 0 to RAND_MAX. The period of this random number generator is very large, approximately

```   16 * ((2^31) - 1).
```

#### So, this is it. It is not random it is actually pseudo-random.

Meaning of pseudorandom from dictionary,

(of a number, a sequence of numbers, or any digital data) satisfying one or more statistical tests for `randomness but produced by a definite mathematical procedure.` most computers have built-in functions which will generate sequences of pseudorandom numbers.`

Aha. We are there. Whatever we discussed so far is making sense.

Also, there can be a requirement, where, for some experiment which uses random numbers has to be reproducible.

So thats the reason. Why random() function in libc is returning same sequence. The same can be achieved even in Python using seed.

```from __future__ import print_function
import random

def main():
for x in xrange(3):
print("Unseeded random number: {}".format(random.random()))

random.seed(5)
for x in xrange(3):
print("Seeded random number: {}".format(random.random()))

if __name__ == '__main__':
main()
```

The output of the above code twice,

```[[email protected] test_random]\$ date && python ~/exp/python/test_random/ran.py
Wed May 20 19:45:46 IST 2015
Unseeded random number: 0.399506141684
Unseeded random number: 0.591102825052
Unseeded random number: 0.00522710909826
Seeded random number: 0.62290169489
Seeded random number: 0.741786989261
Seeded random number: 0.795193565566

[[email protected] test_random]\$ date && python ~/exp/python/test_random/ran.py
Wed May 20 19:45:49 IST 2015
Unseeded random number: 0.888964633885
Unseeded random number: 0.000467464175557
Unseeded random number: 0.0425654580676
Seeded random number: 0.62290169489
Seeded random number: 0.741786989261
Seeded random number: 0.795193565566
```

The same seed returns the same sequence.

So thats the feature of libc, which allows the caller to set `same` or `different` seed each time based on the requirement.

Moral of the story is,

• random numbers generated by computer are only pseudo random numbers.

Seeds used in random numbers are meant for two reasons,

• to increase the degree of randomness

• to make experiment that uses random numbers reproducible

Happy hacking!!!