How random is C#’s random generator? Have you ever thought about this?

This article might be a bit long; so the summary is, **C#’s random generator produces a fairly uniform distribution. The smaller the range, and the larger the number of iterations, the more uniform (eg. variance decreases from 20% to 0.6%).**

Let’s go back to the basics. What is random? Random can mean “a uniform distribution,” meaning if I ask for ten random numbers in the range [1, 10], I expect each number to show up about once, i.e. *all options are equally likely to appear, and appear approximately equally.* Here’s what a uniform distribution looks like:

Contrast this to a “normal distribution,” also known as a “bell curve.” This is something that occurs naturally in a lot of domains (eg. human height, human weight). Here’s what it looks like:

Back to Random for a minute — the problem with computers is that computers are inherently *deterministic* and non-random. So instead of coming up with a *truly* random generator, we have to settle for these so-called “psuedo random number generators” (PRNGs), which are the best randomization we can make in a deterministic world.

The problem with psuedo-random number generators, is that they’re “psuedo” — they’re not *really* random. This can have dire implications in security, where cryptography relies on random number generation. If you could *predict the next series of random numbers,* you could potentially crack the encryption! For this reason, so-called “cryptographically-secure PRNGs” exist, which satisfy some rigorous standard of being “random enough” for cryptography. Phew!

In fact, if you want *real* random, you can check out the HotBits website, which uses an actual, real and real-world random distribution (radioactive decay) to generate random numbers. Very cool.

So, how random is the C# built-in Random class? Let’s take a look. To test this out, I created a small script to generate random numbers from 0 to 99, and to query the random generator 100 * 100 times; this means we can interpret the results as a percentage — if every number occurs roughly 100 times, then it’s uniform; more and less than that is our variance.

Here are what the results looked like:

The results don’t look bad — the distribution is fairly even. You’ll notice that the range of numbers is +-20, which is approximately a 20% margin of error.

Two interesting observations:

**Smaller Range:**A smaller range of numbers (eg. 1-10 instead of 1-100) produces less variation and a more uniform distribution.**More Iterations:**We perform 100*100 iterations; if we performed, say, 100*10000 iterations, we would see less variation.

So is the built-in random number generator “good enough?” Unless you’re building some hardcore security algorithm, the answer is probably “yes.” (And if you’re doing that, there are one or two cryptographically-secure random number generators in the System.Cryptography namespace.)

I would recommend that you try to use a smaller range of numbers if possible, if you really care about a uniform distribution.

Other than that … you can sum up the article as “yes, it really *is* random!”