You have to differentiate between random number generators (RNGs):
True RNGs (TRNGs) will always yield numbers which even after analysing a concurrent series n of them, will not be predictable
Pseudo RNGs (PRNGs) take a seed and calculate a sequence of numbers from it. If that sequence has a length of 3, those three will repeat over and over again
Cryptographically Secure PRNGs (CSPRNGs) generate a sequence of numbers from a seed which cannot be calculated for a sufficiently large series of numbers
Talking about TRNGs, you can easily program such a RNG, but the most important part is a hardware device which generates an unpredictable input to the RNG. One choice of device is a sensor for EM waves from space, which tend to be quite uncalculable. It might yield sequences of the same number, however that's only natural and secure, as you have the same number of possible results for every new random number!
In the world of computers, we only have PRNGs, which take the hash of stuff, like time, current CPU temperature, current CPU boost speed, etc. (depending on the implementation) as input to generate a sequence of random numbers. Most libraries in use today are quite good at it and qualify as CSPRNGs. However, no matter how secure they are, they will always just calculate numbers. There is nothing random in calculating numbers.
One of the problems is that most input parameters in todays regular computers are quite predictable. Let's take a PRNG on a server we want to attack which takes the above mentioned input parameters. The time is known. An attacker might find out about the used server hardware and infrastucture and manipulate it to have a load of 100%. Then the CPU will have a predictable temperature and a predictable boost speed (with minimal deviations). So we can feed our local algorithm with the input values we predict and get the same "random" number the PRNG on the server would calculate. That prediction can be used to break every known cryptographic algorithm which works with a generated key. In reality, it's not that easy, of course ;)
In order to get "random numbers" which don't repeat the same number twice in a row, you would have to manipulate a PRNG. There is no implementation available (because it's a trivial special case), but you can build one yourself by caching the previously generated number, and if the next number is the same as the one in the cache, have the RNG generate a new number. However, that compromises security, because the random number becomes even more predictable (a number cannot occur twice in a row)
The math for that:
a regular RNG with a number space of k will have a chance of 1/k for a certain number
your manipulated RNG with a number space of k will have a chance of 1/(k-1) for a certain number, because the previous number must not be used (except for the first number to be generated, which is 1/k)
Simple example with a number space of {0..9} (10 elements): Each element has a chance of 1/10=0.10 to occur. If you manipulate it, the chance will be 1/9=0.11, which is higher when someone has to guess the next number
// Sample implementation in JS; Math.random() is not a CSPRNGfunctionmanipulatedPRNG(min, max) {
let rn;
do {
// if you only want to return integers,// you will have to use Math.round() here
rn = Math.random() * (max - min) + min;
}
while (manipulatedPRNG._cachedRN === rn);
manipulatedPRNG._cachedRN = rn;
return rn;
}
You have to differentiate between random number generators (RNGs):
Talking about TRNGs, you can easily program such a RNG, but the most important part is a hardware device which generates an unpredictable input to the RNG. One choice of device is a sensor for EM waves from space, which tend to be quite uncalculable. It might yield sequences of the same number, however that's only natural and secure, as you have the same number of possible results for every new random number!
In the world of computers, we only have PRNGs, which take the hash of stuff, like time, current CPU temperature, current CPU boost speed, etc. (depending on the implementation) as input to generate a sequence of random numbers. Most libraries in use today are quite good at it and qualify as CSPRNGs. However, no matter how secure they are, they will always just calculate numbers. There is nothing random in calculating numbers.
One of the problems is that most input parameters in todays regular computers are quite predictable. Let's take a PRNG on a server we want to attack which takes the above mentioned input parameters. The time is known. An attacker might find out about the used server hardware and infrastucture and manipulate it to have a load of 100%. Then the CPU will have a predictable temperature and a predictable boost speed (with minimal deviations). So we can feed our local algorithm with the input values we predict and get the same "random" number the PRNG on the server would calculate. That prediction can be used to break every known cryptographic algorithm which works with a generated key. In reality, it's not that easy, of course ;)
In order to get "random numbers" which don't repeat the same number twice in a row, you would have to manipulate a PRNG. There is no implementation available (because it's a trivial special case), but you can build one yourself by caching the previously generated number, and if the next number is the same as the one in the cache, have the RNG generate a new number. However, that compromises security, because the random number becomes even more predictable (a number cannot occur twice in a row)
The math for that:
// Sample implementation in JS; Math.random() is not a CSPRNG function manipulatedPRNG(min, max) { let rn; do { // if you only want to return integers, // you will have to use Math.round() here rn = Math.random() * (max - min) + min; } while (manipulatedPRNG._cachedRN === rn); manipulatedPRNG._cachedRN = rn; return rn; }