I am working on a static class to provide random values for my program, but there are some issues with implementing the equivalent of the Random.Next(int maxValue) functionality:
public class CRandom {
static readonly byte[] randomSet;
static readonly Func<int> closedIndex;
static CRandom() {
randomSet = new byte[60000000];
closedIndex = _ClosedIndex(0);
RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider();
Gen.GetBytes(randomSet);
}
public static int Next() {
int index = closedIndex();
return Convert.ToInt32(randomSet[index]);
}
public static int Next(int maxValue) {
int index = closedIndex();
byte[] remainingSet = randomSet.Skip(index + 1).ToArray();
byte next = remainingSet.First(x => Convert.ToInt32(x) < maxValue);
return Convert.ToInt32(next);
}
public static Func<int> _ClosedIndex(int seed) {
// seed is the initial value
int _index = seed - 1;
Func<int> del = new Func<int>(() =>
{ // always returns auto-incremented value
_index++;
return _index;
});
return del;
}
}
Basically what it does is fill up a static/readonly byte array of random values and in the case of the Next(maxValue) method just gets the next value thats in range but hasn’t been used before. However trying out Next(100) in a loop is giving these results, which obviously aren’t random:
53
20
20
34
34
73
73
73
73
This is also a very slow way of doing it. I’m sure there is a better way but I don’t know quite how Random.Next() works under the hood.
MSDN Magazine has a very detailed article about this exact topic.
It’s more complicated than you think.
He wrote the following class; however, read the article for important notes about randomness.