Home
C#
Random Number Examples
This page was last reviewed on Nov 10, 2023.
Dot Net Perls
Random. Programs often need to generate random data. An ID or user name could be based on random data. The Random class in C# helps here—it is easy to use and fast.
For using the Random class, the important part to remember is that you should create the class once. Then reuse it to get a random stream of numbers.
Random class. Random, a class, is available when we include (or reference) the System namespace. We use Random and Next() with 2 arguments.
Argument 1 The first argument to Next() is the inclusive minimum number allowed by the random number generator.
Argument 2 This argument is an exclusive maximum. So it never occurs in the output—all numbers must be lower.
using System; // ... Create new Random object. Random random = new Random(); // ... Get 3 random numbers. // These are always 5, 6, 7, 8 or 9. Console.WriteLine(random.Next(5, 10)); Console.WriteLine(random.Next(5, 10)); Console.WriteLine(random.Next(5, 10));
6 5 9
Static. A static thing only has one instance. A static Random improves programs. Here the Random object is stored as a static variable. Methods that use it will still get good random ints.
Part 1 We call the UseStatic method 2 times in the Main method. Each call uses the same Random instance.
Part 2 In UseStatic, we reference the static Random instance, and call Next() on it. We print the random number.
Console.WriteLine
Important If we created a new Random at the method level as a local, a problem would arise. The time-dependent seed would repeat itself.
using System; class Program { static void Main() { // Part 1: call a method that uses class-level Random. UseStatic(); // Call the same method. // ... The random number sequence will still be random. UseStatic(); } static Random _random = new Random(); static void UseStatic() { // Part 2: use class-level Random. // ... When this method is called many times, it still has good Randoms. int result = _random.Next(); // If this method declared a local Random, it would repeat itself. Console.WriteLine("STATIC RANDOM: " + result); } }
STATIC RANDOM: 810380956 STATIC RANDOM: 123622001
Repeated randoms. This is a bad example of code—do not use it in a real program. When we create a Random object, its seed is based on the time.
So If we create many Random objects at the same time (or close in time) our random numbers will repeat.
Tip Use a field or pass a Random as an argument to avoid repeated random numbers.
class Program { static void Main() { Test(); Test(); Test(); } static void Test() { // Create random and use it. // ... This is time-dependent, so can repeat if called many times. var random = new System.Random(); System.Console.WriteLine("CURRENT: " + random.Next()); } }
CURRENT: 747025912 CURRENT: 747025912 CURRENT: 747025912
Exception, minValue. When calling Next(), be careful that the "minimum value" is lower than the "maximum value." So the first argument is always lower than the second.
using System; class Program { static void Main() { var random = new Random(); // First argument must be lower than the second. int result = random.Next(20, 10); } }
Unhandled Exception: System.ArgumentOutOfRangeException: 'minValue' cannot be greater than maxValue. Parameter name: minValue at System.Random.Next(Int32 minValue, Int32 maxValue) at Program.Main()...
Max. Here is another example of the maxValue parameter on the Next method. When we pass an integer to Random.Next(), we get a result in the range of 0 to maxValue minus 1.
Important We will not get the actual parameter argument we passed, as the top is exclusive.
Also Another option is to pass the Next() method 2 parameters. The lower bound is inclusive, but the upper one is not.
using System; class Program { static void Main() { F(); F(); F(); F(); F(); F(); } static Random _r = new Random(); static void F() { int n = _r.Next(5); // Can return 0, 1, 2, 3, or 4. Console.WriteLine(n); } }
2 1 1 0 3 2
Modulo division can be used on random numbers. Here we get 10 random numbers, then use modulo to get an index into a small array. Then we increment random elements.
Modulo
Note Using arguments to Next() that are in the correct range would be better than using modulo, as the code is more direct and simpler.
However If we wish to use a single random number in multiple ways, modulo division can help here.
Tip If the array length is 3, and we have a random number and use modulo division by 3, we get the values 0, 1 and 2.
using System; int[] array = new int[3]; var random = new Random(); // Get 10 random numbers, then use modulo to increment array elements. for (int i = 0; i < 10; i++) { int result = random.Next(0, 100); int modulo = result % array.Length; array[modulo]++; } // Display the end result. for (int i = 0; i < array.Length; i++) { Console.WriteLine("ARRAY {0} = {1}", i, array[i]); }
ARRAY 0 = 2 ARRAY 1 = 4 ARRAY 2 = 4
Randomize string. This example is a bit more complex. It randomizes the chars in a string. It sorts on a random number to shuffle data.
Here The program uses the LINQ method syntax, which combines the OrderBy with a lambda expression.
OrderByDescending
Result ToArray converts the enumerable letters in the statement to a string again, producing the final result: a randomized string.
ToArray
String Constructor
using System; using System.Linq; // The source string. const string original = "senators"; // The random number sequence. Random num = new Random(); // Create new string from the reordered char array. string rand = new string(original.ToCharArray(). OrderBy(s => (num.Next(2) % 2) == 0).ToArray()); // Write results. Console.WriteLine("original: {0}\r\nrand: {1}", original, rand);
original: senators rand: tossenar
Bytes. You can also call the NextBytes method on the Random type to acquire a random byte array. Each byte has the decimal range of 0 to 255.
Info The NextBytes method allows you to get a random value of arbitrary length in one method invocation.
Tip While an integer is only 4 bytes, you can use NextBytes to get much more random data at once.
using System; class Program { static void Main() { // Put random bytes into this array. byte[] array = new byte[8]; // Use Random class and NextBytes method. // ... Display the bytes with the following method. Random random = new Random(); random.NextBytes(array); Display(array); random.NextBytes(array); Display(array); } static void Display(byte[] array) { // Loop through and display bytes in the array. foreach (byte value in array) { Console.Write(value); Console.Write(' '); } Console.WriteLine(); } }
177 209 137 61 204 127 103 88 167 246 80 251 252 204 35 239
RNGCryptoServiceProvider. The Random class is not as random as possible—do not use it for cryptography. For cryptography in .NET, use the RNGCryptoServiceProvider class.
RNGCryptoServiceProvider
Step 1 We create a new instance of the RNGCryptoServiceProvider with a using statement.
Step 2 We create a byte array of 10 elements. Then we call GetBytes() to populate it with random data.
Step 3 We use a foreach-loop and the Console.Write method to print out all of our random data.
using System; using System.Security.Cryptography; // Step 1: create object. using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) { // Step 2: create and fill buffer. var data = new byte[10]; rng.GetBytes(data); // Step 3: display random bytes. foreach (var d in data) { Console.Write(d); } Console.WriteLine(); }
1261711625221018917915387232
RandomNumberGenerator. Using RNGCryptoServiceProvider is obsolete and causes a warning when compiled. Instead, in .NET 7, we can use the RandomNumberGenerator static class and invoke Create.
Step 1 We call RandomNumberGenerator.Create() in a using statement to create the required object.
Step 2 As with calling RNGCryptoServiceProvider directly, we can use GetBytes() and pass an empty byte array.
byte Array
Step 3 Here we display the bytes that were placed into our byte array buffer by GetBytes.
using System; using System.Security.Cryptography; // Step 1: create object with static method. using (var rng = RandomNumberGenerator.Create()) { // Step 2: create buffer and call GetBytes on it to fill it. var temp = new byte[8]; rng.GetBytes(temp); // Step 3: print out the bytes. foreach (var b in temp) { Console.Write(b); } Console.WriteLine(); }
106851631498298176114
Benchmark, random cache. Suppose we want many random ints, but having high-quality random numbers is not important. We can pre-populate a List with random ints.
And With a modulo expression, we can index those ints and use them in place of a call to Random.Next.
Version 1 This version of the code repeatedly invokes the Random.Next method to get random ints.
Version 2 This version uses a List element access of precomputed random ints. This approach might work in some programs.
Result It is faster to access precomputed ints. We could even use a static list and avoid the startup time cost.
using System; using System.Collections.Generic; using System.Diagnostics; class Program { static Random _random = new Random(); static List<int> _randomCache = new List<int>(); static void AddRandoms() { // Add random numbers to a list for later use. for (int i = 0; i < 1000; i++) { _randomCache.Add(_random.Next()); } } const int _max = 10000000; static void Main() { // Precompute some random ints. AddRandoms(); // Version 1: get new random int. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int random = _random.Next(); if (random < 0) { return; } } s1.Stop(); // Version 2: use cached random int from list. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int random = _randomCache[i % _randomCache.Count]; if (random < 0) { return; } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); } }
8.93 ns Random.Next() 2.79 ns Random Cache (List)
Summary. Be careful of creating new Randoms—the results may start to repeat. Instead, reusing the same Random is a more ideal approach to pseudo-random number generation in C#.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Nov 10, 2023 (simplify).
Home
Changes
© 2007-2024 Sam Allen.