Developer

Working with random numbers in .NET applications

Random number generation is a common programming endeavor, but many developers are unaware of the true nature of the random numbers generated by a system. Learn more about random numbers and how to use them in your .NET applications.

TechRepublic's free .NET newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET. Automatically sign up today!

Generating random numbers is often a hot topic for programmers. The reason is that seemingly random numbers are most often not genuinely random. This is due to the deterministic algorithm utilized by a platform like .NET. Deterministic systems leave nothing to chance; they're lawful out of necessity; and they conform to the ideal of a machine in which wear and tear and mechanical failures are absent. Modern computers are conceived as deterministic machines.

The Random class

The .NET Framework provides the Random class, which allows you to generate a number or a series of numbers to be used accordingly. You may be wondering why .NET bothers to include the Random class. The system may be deterministic, but it can be utilized to create values that meet a need. The result is pseudo-random numbers, but you must be careful to properly use the Random object to ensure different values.

Planting a seed

Any pseudo-random number formula depends on the seed value to start the sequence. If you start with the same seed, you will get the same sequence of values from the formula. The .NET Framework's Random class allows you to specify the seed value or allow the system to generate it.

To create a random and unpredictable sequence, the seed must be a truly random number. To get this truly random number for the seed, most programs use the current date and time, converted to an integer value. The theory is this is a different number every time the code executes, but the speed of modern computers negates this assumption.

The next code snippet creates an instance of the Random class in VB.NET:

Dim randObj As New Random(0)
Console.WriteLine(randObj.Next().ToString())

This code creates a Random object using a seed value of zero. The problem with this approach is that it creates the same value(s) every time it is used since the seed value is a constant. It produces the number 1559595546 on my machine. The same code in C# follows:

Random randObj = new Random(0);
Console.WriteLine(randObj.Next().ToString());

The Random class does provide an empty constructor. It initializes a new instance of the Random class, using a time-dependent default seed value. That is, it uses the system clock. Therefore, you could rewrite the previous code using this approach:

Random randObj = new Random();
Console.WriteLine(randObj.Next().ToString());

You may run this code a few times and notice that values are not repeated. Let's take a closer look at the methods available in the Random class.

Random class members

The Random class includes various methods for creating and accessing values. Here is a subset of these methods:

  • Next: Returns a random number generated using the seed value.
  • NextBytes: Fills the elements of a specified array of bytes with random numbers.
  • NextDouble: Returns a random number between 0.0 and 1.0.

All of these methods are used to access numbers generated by the object. They should be used in succession to work with multiple random numbers or a series of random numbers. This is due to the fact that two or more Random objects initialized with the same seed will produce the same series.

The Next method

The Next method supports three signatures. We've used the first approach where no parameter is used and a random number is returned. The second approach accepts one parameter that signals a maximum value, thus the random number returned is less than that value. The last signature accepts both minimum and maximum values, so a value is returned that is between these values. The next VB.NET code sample demonstrates each:

Dim randObj As New Random
Console.WriteLine(randObj.Next().ToString())
Console.WriteLine(randObj.Next().ToString())
Console.WriteLine(randObj.Next().ToString())
' Use a maximum constraint
Console.WriteLine(randObj.Next(10).ToString())
Console.WriteLine(randObj.Next(100).ToString())
Console.WriteLine(randObj.Next(1000).ToString())
' Use minimum and maximum constraints
Console.WriteLine(randObj.Next(1, 100).ToString())
Console.WriteLine(randObj.Next(101, 1000).ToString())
Console.WriteLine(randObj.Next(1001, 10000).ToString())

The C# equivalent follows:

Random randObj = new Random();
Console.WriteLine(randObj.Next().ToString());
Console.WriteLine(randObj.Next().ToString());
Console.WriteLine(randObj.Next().ToString());
// Use a maximum constraint
Console.WriteLine(randObj.Next(10).ToString());
Console.WriteLine(randObj.Next(100).ToString());
Console.WriteLine(randObj.Next(1000).ToString());
// Use minimum and maximum constraints
Console.WriteLine(randObj.Next(1, 100).ToString());
Console.WriteLine(randObj.Next(101, 1000).ToString());
Console.WriteLine(randObj.Next(1001, 10000).ToString());

The NextBytes method

The NextBytes method allows you to populate a byte array with random values. This allows you to quickly assemble a batch of values. The next VB.NET example shows how this may be used.

Dim randObj As New Random
Dim randArray(20) As Byte
randObj.NextBytes(randArray)
Dim i As Integer
For i = 0 To (randArray.Length â€" 1)
Console.WriteLine(randArray(i))
Next i

The result is the byte array populated with numbers generated by repeated calls to the Random object. The C# equivalent follows:

Random randObj = new Random();
Byte[] randArray = new Byte[20];
randObj.NextBytes(randArray);
for (inti = 0; i < randArray.Length; i++)
Console.WriteLine(randArray[i]);

The NextDouble method

The NextDouble method returns a double value as opposed to an integer. The value is in the range of 0.0 and 1.0.

Randomness and security

One application of random numbers is security. Many cryptography algorithms depend upon random numbers; therefore, the algorithms are only as strong as the random numbers. For this reason, .NET's basic Random class is not a good choice for security. However, .NET'sSystem.Security.Cryptography namespace does include the RNGCryptoServiceProvider class for working with a cryptographic Random Number Generator (RNG). The effectiveness of it is debatable and beyond the scope of this article.

Know the application

It is a common assumption that random numbers are really random, but this just isn't true. The algorithm modern computers use makes these numbers often predictable, but values like the system clock can be used to generate pseudo-random numbers. Keep this background information handy when random numbers are a necessity in your application.

About

Tony Patton has worn many hats over his 15+ years in the IT industry while witnessing many technologies come and go. He currently focuses on .NET and Web Development while trying to grasp the many facets of supporting such technologies in a productio...

0 comments

Editor's Picks