Sunday, November 27, 2005 5:10 PM
System.Random class SDK indicates that Pseudo-random numbers are chosen with equal probability from a finite set of numbers. The chosen numbers are not completely random because a definite mathematical algorithm is used to select them, but they are sufficiently random for practical purposes. The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated.
for(int index=0; index<10; index++)
{ int seed = (int) System.DateTime.Now.Ticks;
System.Random random = new Random(seed);
System.Diagnostics.Debug.WriteLine(random.NextDouble());
}
The above code shows that it generates same "random" numbers multiple times, because of .NET code execution is really fast and returns same
System.DateTime.Now.Ticks values for multiple instructions within a loop.
To resolve this issue, we could add delay using Thread.Sleep function call, which result in application performance impact:
for(int index=0; index<10; index++)
{ int seed = (int) System.DateTime.Now.Ticks;
System.Random random = new Random(seed);
System.Diagnostics.Debug.WriteLine(random.NextDouble());
System.Threading.Thread.Sleep(10);
}
System.GUID has a very low probability of being duplicated and provides more unique seed values.
for(int index=0; index<10; index++)
{ string guid = System.Guid.NewGuid().ToString("N").Replace("a", "").Replace("b", "").Replace("c", "").Replace("d", "").Replace("e", "").Replace("f", ""); System.Diagnostics.Debug.WriteLine(guid); //Random very large number/string;
int seed = int.Parse(guid.Substring(0, 5));
System.Random random = new Random(seed);
System.Diagnostics.Debug.WriteLine(random.NextDouble());
}
The best solution will be using Cryptography.RandomNumberGenerator class, which generators cryptographically strong random values as follow:
public const string ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public const string NUMERIC = "0123456789";
public const string ALPHA_NUMERIC = ALPHA + NUMERIC;
//
// Creates a random password
//
public static string GetRandomNumber(int length, string characterSet)
{ string randomData = "";
int position = 0;
byte[] data = new byte[length];
int characterSetLength = characterSet.Length;
System.Security.Cryptography.RandomNumberGenerator random = System.Security.Cryptography.RandomNumberGenerator.Create();
random.GetBytes(data);
for (int index = 0; (index < length); index++)
{ position = data[index];
position = (position % characterSetLength);
randomData = (randomData + characterSet.Substring(position, 1));
}
return randomData;
}
// To execute the function, Call:
// GetRandomNumber(5, ALPHA_NUMERIC);