C# RNGCryptoServiceProvider

The C# programming language

RNGCryptoServiceProvider generates high-quality random numbers. With it, we use an RNG—random number generator—that is as random as possible in the C# language. This helps in applications where random numbers must be completely random. This type has a cost: it reduces performance over the Random type.

This C# article tests RNGCryptoServiceProvider. This type returns high-quality random numbers.

Example

Note

The most useful method on RNGCryptoServiceProvider is the GetBytes method. Also, because this type implements Dispose, you can enclose it in a using-statement. Here, we fill a four-byte array with GetBytes ten times, and then use BitConverter.ToInt32 to change those four-byte arrays into integers. This yields random integers.

BitConverter Examples
Program that uses RNGCryptoServiceProvider [C#]

using System;
using System.Security.Cryptography;

class Program
{
    static void Main()
    {
	using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
	{
	    // Buffer storage.
	    byte[] data = new byte[4];

	    // Ten iterations.
	    for (int i = 0; i < 10; i++)
	    {
		// Fill buffer.
		rng.GetBytes(data);

		// Convert to int 32.
		int value = BitConverter.ToInt32(data, 0);
		Console.WriteLine(value);
	    }
	}
    }
}

Output

461315061
-1277834804
-1239389884
-1540126655
1669339804
1436197105
-473414988
-264059284
-1832694377
-1929982707

Output description. As you can see, the output is pretty random-looking. I haven't run any tests of randomness on RNGCryptoServiceProvider or compared it to the Random type, but random number generators implemented with cryptographic algorithms are suitable for most program requirements for randomness.

Random versus RNGCryptoServiceProvider

Question and answer

So when should you use Random and when should you use the slightly more complicated RNGCryptoServiceProvider? My expectation is that for most programs, Random is sufficient and preferable due to its simplicity. But for important programs RNGCryptoServiceProvider is better because it is less prone to problems with its randomness.

Note: The Random type does not use the RNGCryptoServiceProvider internally. The implementations are different.

Benchmark

Performance optimization

Because I had absolutely nothing better to do, I decided to quantify the performance of RNGCryptoServiceProvider and Random. The inner loop contained only the call to GetBytes and ToInt32 for RNGCryptoServiceProvider, and Next() for Random. The objects used were created outside of the inner loop and not timed.

Benchmark results

Time for one random int from RNGCryptoServiceProvider: 2796.19 ns
Time for one random int from Random:                      9.30 ns

Result summary. It's clear from these results that you might end up with a slow program if you overuse RNGCryptoServiceProvider: this type is over 300 times slower when used as shown than the Random type.

Summary

We looked at the RNGCryptoServiceProvider type in the C# language and demonstrated its use in a simple program. With this type, you can fill byte arrays with random values. Then you can convert those byte arrays to integral types or use them directly.

Random Number
.NET