Can't understand why I need to seed using srand - random

When we need a random number we use srand once to initialize the seed and after that we can use rand. Why do we need to seed using srand? For example srand(time(Null)); Can't we just use rand() % 99999? Am I missing something in the concept of these functions?

Here's the thing,
You actually don't need to seed your random number generator. Go ahead, try it without!
BUT, you will always get the same sequence of 'random' numbers.
Pseudo-random number generators such as rand() only generate random-looking sequences. If you just start them from the 'beginning' every time, they will of course look the same.
Seeding the generator is a good way to get numbers that actually appear 'properly' random. If you seed with the time, you are starting somewhere 'random' in the sequence. Note that picking time values close together usually gives two sequences that are also very different.
You can seed with whatever you like. For example, if you have lots of threads using lots of generators, the time is a bad idea because the time may well be the same for multiple threads.
There is no clear 'good' value for the seed, so it is usually not seeded by default. This can also be a good thing if you want to 're-run' a randomised algorithm with exactly the same input: just set the seed to be the same seed.

srand(0) will always return the same deterministic sequence of values, although those values will appear random.
Knowing your seed will allow an attacker to determine every number you generate.
By setting a seed, you effectively create a different sequence.
srand(0) may be entirely acceptable to your needs, if you only need the appearence of random.

Related

Random Number Generator that Allows "Indexing"

I hope it's not too obvious a question: is there a random number generation algorithm that doesn't depend on previously returned values, so that I can get (for example) the 50th number in the sequence, without computing the previous 49?
The reason is that I am making roguelike that will be persistent (so that I can recreate the exact same level from the same seed), but to compute certain features of each level, I don't want to have to "compute" all previous features just to get the random number generator to the correct "state" of having been used, for example, 100 times so far. I would like to be able to query the 101st random number without determining previous values so that the program can create level features separately.
You can encrypt ordinary sequence number [1..N] with any cipher,
and by this way - generate unique pseudorandom value for each SeqNo.
If you use a linear congruential random number generator, it is trivial to compute the $n$-th element generated from a given seed. But it is probably easier just to stash away the state at the "interesting" points of the game.
OTOH, if you want to "restart" the game at a certain point, you'll presumably want to be able to recreate the dungeon's features, but (due to different player actions) the RNG usage will be different from then on. I.e., if started at the same point, if I shoot twice at a monster the RNG will be used more times than if I just run away; the next item generated will get different values. Perhaps what you really want is several independent random number streams, and saving the states as needed?
There are lots of roguelike games around, mostly open source. Some are limited/small (from "build a game in a day" sort of competitions), and might make a good starting point for you. Why start your own, and not hack on an existing one?

What is a seed in relation to a random number generation algorithm and why is computer time used to create this seed more often than not?

I read that seeds are used to initialize random number generators. But seems like the randomness of the seed doesn't matter much for getting good randomness from the generator. So I want to understand what is a seed actually? Why is it called so? And lastly why time in a computer system is used to generate such seeds?
A pseudo-random number generator produces a sequence of numbers. It isn't truly random, but generally a mathematical calculation which produces an output that matches some desirable distribution, and without obvious patterns. In order to produce such a sequence, there must be state stored for the generator to be able to generate the next number in that sequence. The state is updated each time using some part of the output from the previous step.
Seeding explicitly initialises this state. A 'seed' is a starting point, from which something grows. In this case, a sequence of numbers.
This can be used either to always generate the same sequence (by using a known constant seed), which is useful for having deterministic behaviour. This is good for debugging, for some network applications, cryptography, etc.
Or, in situations where you want the behaviour to be unpredictable (always different each time you run a program, a card game perhaps), you can seed with a number likely to be continually changing, such as time.
The 'randomness' of the sequence does not depend on the seed chosen, though it does depend on not reseeding the sequence.

Why are some random() functions deemed "not secure?"

I've heard people being warned all over the place not to rely on a language's random() function to generate a random number or string sequence "for security reasons." Java even has a SecureRandom class. Why is this?
When people talk about predicting the output of a random number generator, they don't even need to get the actual "next number". Even something subtle like noticing that the random numbers aren't evenly distributed, or that they never produce the same number twice in a row, or that "bit 5 is always set", can go a long way towards turning an attack based on guessing a "random" number from taking years, to taking days.
There is a tradeoff, generally, too. Without specific hardware to do it, generating large quantities of random numbers quickly can be really hard, since there isn't enough "randomness" available to the computer so it has to fake it.
If you're not using the randomness for security (cryptography, passwords, etc), but instead for things like simulations or numerical work, then it doesn't matter too much if they're predictable, only that they're statistically random.
Almost every random number generator is 'pseudo random' in that it uses a table of random numbers or a predictable formula. A seed is sometimes used to "start" the random sequence at a specific point, e.g. seedRandom(timer).
This was especially prevalent in the days of BAsIC programming, because it's random number generator always started at exactly the same sequence of numbers, making it unusable for any kind of GUID generation.
Back in the day, the Z-80 microprocessor had a truly random number generator, although it was only a number between 0 and 127. It used a processor cycle function and was unpredictable.
Pseudo-random numbers that can be determined in advance can lead to security holes that are vulnerable to a random number generator attack.
Predictability of a random number is a big issue. Most "random" functions derive their value from time. Given the right set of conditions you could end up with two "random" numbers of a large value that are the same.
In windows .NET world CPRNG (Cryptographically secure pseudo random number generator) can be found in System.Security.Cryptography.RandomNumberGenerator through underlying win32 APIs
In Linux there is a random "device"

True random vs. Pseudo Random (can you pseudo-random true-randomness)

Ok, so this question involves a bit of a forward. Bear with me.
There's this website random.org (and others like it) that claim to use some sort of quantum process or another to produce true random numbers.
If one were to query this site over and over and develop a massive log of true random numbers. This log is then rearranged by a program to mix it up as randomly as it can. Is the resulting output less random than when it started? By how much?
Any good/cheap further reading on the subject?
Reordering random numbers by a fixed permutation does not change the degree of randomness.
So if you have a perfect random number source, the same bits reshuffled will be equally random. This will be true if whether the "shuffle" is a fixed reordering (e.g. reversing all the bits) or a shuffle generated by a pseudo-random number generator (which is really a very obfuscated way of defining a fixed re-ordering from some initial seed).
This is provable from the underlying maths - if you reorder a set of truly independent identically distributed random variables then the resulting distribution will be the same as the one that you started with. Hence it is equally random.
However, this does not work if the shuffling is dependent on the values of the random bits in some way. If, for example, you sort the bits rather than permuting them then you won't have very good random output :-).
It would depend on how you reorder them. If you used pseudo random function to do it the results will likely be less random. If you use the true random to reorder itself it will not be more random.
One thing that people forget is the reason to use pseudo random function over some true random numbers is repeatedly and testing. If you get some unexpected results using pseudo random function will make looking at the possible problem easer.
If you have a process that needs N 'random' numbers, you can take N from the site, and use them, IN THAT ORDER, and all will be well. If you reshuffle them, you will make them less random.
If you need an ongoing supply of random numbers, then the question is the relative quality of some pseudo-random juggle of these versus what would happen if you had a true random sequence.
Since, however, linux and windows both supply real random numbers by harnessing hardware entropy, why not just use those?

What is the difference between a non-secure random number generator and a secure random number generator?

As the title says: What is the difference between a non-secure random number generator and a secure random number generator?
No computationally feasible algorithm should:
recover the seed, or
predict the "next bit"
for a secure random number generator.
Example: a linear feedback shift register produces lots of random numbers out there, but given enough output, the seed can be discovered and all subsequent numbers predicted.
A secure random number should not be predictable even given the list of previously generated random numbers. You'd typically use it for a key to an encryption routine, so you wouldn't want it guessable or predictable. Of course, guessable depends on the context, but you should assume the attacker knows all the things you know and might use to produce your random number.
There are various web sites that generate secure random numbers, one trusted one is hotbits. If you are only doing the random number generation as a one off activity, why not use a lottery draw result, since it's provably random. Of course, don't tell anyone which lottery and which draw, and put those numbers through a suitable mangle to get the range you want.
With just a "random number" one usually means a pseudo random number. Because it's a pseudo random number it can be (easily) predicted by an attacker.
A secure random number is a random number from a truly random data source, ie. involving an entropy pool of some sorts.
Agree with Purfiedeas. There is also nice article about that, called Cheat Online Poker
A random number would probably mean a pseudo random number returned by an algorithm using a 'seed'.
A secure random number would be a true random number returned from a device such as a caesium based random number generator (which uses the decay rate of the caesium to return numbers). This is naturally occurring and can't be predicted.
It probably depends on the context, but when you are comparing them like this, I'd say "random number" is a pseduo random number and a "secure random number" is truly random. The former gives you a number based on a seed and an algorithm, the other on some inherintly random function.
It's like the difference between AES and ROT13.
To be less flippant, there is generally a tradeoff when generating random numbers between how hard it is and how predictable the next one in the sequence is once you've seen a few. A random number returned by your language's built-in rand() will usually be of the cheap, predictable variety.

Resources