I know that the Random class can generate pseudo-random numbers but is there a way to generate truly random numbers?
12 Answers
The answer here has two main sides to it. There are some quite important subtleties to which you should pay due attention...
The Easy Way (for simplicity & practicality)
The RNGCryptoServiceProvider
, which is part of the Crypto API in the BCL, should do the job for you. It's still technically a pseudo-random number generated, but the quality of "randomness" is much higher - suitable for cryptographic purposes, as the name might suggest.
There are other crypographic APIs with high quality pseudo random generaters available too. Algorithms such as the Mersenne twister are quite popular.
Comparing this to the Random
class in the BCL, it is significantly better. If you plot the numbers generated by Random
on a graph, for example, you should be able to recognise patterns, which is a strong sign of weakness. This is largely due to the fact that the algorithm simply uses a seeded lookup table of fixed size.
The Hard Way (for high quality theoretical randomness)
To generate truly random numbers, you need to make use of some natural phenomenon, such as nuclear decay, microscopic temperature fluctuations (CPU temperature is a comparatively conveient source), to name a few. This however is much more difficult and requires additional hardware, of course. I suspect the practical solution (RNGCryptoServiceProvider
or such) should do the job perfectly well for you.
Now, note that if you really do require truly random numbers, you could use a service such as Random.org, which generates numbers with very high randomness/entropy (based on atmospheric noise). Data is freely available for download. This may nonetheless be unnecessarily complicated for your situation, although it certainly gives you data suitable for scientific study and whatnot.
The choice is yours in the end, but at least you should now be able to make an informative decision, being aware of the various types and levels of RNGs.

- 144,213
- 56
- 264
- 302
-
12Thanks for the tip, I'll try the RNGCryptoServiceProvider. I might try some nuclear decay as well... – Max Aug 05 '09 at 15:56
-
See http://japikse.blogspot.com/2008/10/random-numbers-in-c.html for a good example – Dan Diplo Aug 05 '09 at 15:56
-
1@Max: Hehe... I should note that a significantly easier method would be to monitor CPU temperature, since that's the most readily available source. But yeah, do check out the `RNGCryptoServiceProvider` first. If you care to describe the context, I can confirm whether this will be sufficient for your usage. – Noldorin Aug 05 '09 at 16:03
-
I was trying random.org and got 33 twice in a row. That's one *very* random coincidence! :) – Douglas Tosi Aug 05 '09 at 16:23
-
@Douglas: Yep, though it doesn't in itself indicate that the generator is one bit less random. ;) As Dan Diplo pointed out, see http://xkcd.com/221/ - it's perfectly correct. – Noldorin Aug 05 '09 at 16:27
-
1@Dogulas - That's not THAT hard. The chance of getting the same number 2 times in a row (assuming you used the 1-100 generator on the front page) is 1% – ryeguy Aug 05 '09 at 16:29
-
2@Douglas - If you *never* got repeating numbers, that would be a sign of less-than-total randomness. – Jim Raden Aug 05 '09 at 16:41
-
5I just tried that generator on the front page, and I got 25 followed by 43. Two *completely unrelated numbers*, how unlikely is that!? This kind of amazing occurrence sends shivers down my spine. – Daniel Earwicker Aug 05 '09 at 21:47
-
1"Technically a PRNG". That's _not_ a technicality - there are fundamental differences between using a real RNG and a PRNG. – Nick Johnson Aug 06 '09 at 08:31
-
3@Nick: I say technically simply because PRNGs are often referred to just as RNGs... but yeah, I think I've made a clear distinction between the two sorts and their methods. – Noldorin Aug 06 '09 at 08:49
short answer: It is not directly possible to generate TRULY RANDOM NUMBERS using only C# (i.e. using only a purely mathematical construction).
long(er) answer: Only by means of employing an external device capable of generating "randomness" such as a white noise generator or similar - and capturing the output of that device as a seed for a pseudo random number generator (PRG). That part could be accomplished using C#.

- 54,171
- 16
- 118
- 151
-
1+1 - gets to the essence of the problem. By definition, nothing geneerated by purely algorithmic means can be truly random. You need an external source of analog randomness such as a device that measures cosmic background radiation. – ConcernedOfTunbridgeWells Aug 05 '09 at 15:54
-
1Very interesting to learn that a computer is not capable of producing something that seems so simple. Couldn't they use other elements like CPU temperature? – Max Aug 05 '09 at 16:02
-
1@Max: You've hit it spot on. See my comment on my own post regarding that. CPU temperature is still far from accessible on all machines however - it might be a good solution for server devices. – Noldorin Aug 05 '09 at 16:05
-
2@Max: Randomness is one of those things that is elusive because it seems simple enough as a concept but the task of generating it (artificially - or mathematically) is terribly complicated if not impossible – Mike Dinescu Aug 05 '09 at 16:20
-
1But the statement that it is impossible using C# and a "Computer" is not true. The COmputer is a real physical system and has a lot of randomness in its operation. Just need the write analog monitoring device to capture it - e.g. You could point the inbuilt mike at the fan and catch some noise. – whatnick Sep 26 '09 at 05:24
-
The statement that it's impossible using C# and computer is largely true. You can get something random, but getting something random and independent, identically distributed is much trickier. For instance, capturing noise from the fan, you are likely to get something periodical. Capturing temperature, you are likely to get some correlation between observations. – Mathias Nov 30 '12 at 21:57
-
@Max, randomness is not that easy even for you. Just generate a few random numbers yourself, I bet the pseudo random numbers you generate with C# are far better than you can do :) – Adi May 03 '13 at 08:59
True random numbers can only be generated if there is a truly random physical input device that provides the seed for the random function.
Whether anything physical and truly random exists is still debated (and likely will be for a long time) by the science community.
Psuedo-random number generators are the next best thing and the best are very difficult to predict.

- 108,238
- 20
- 242
- 324
As John von Neumann joked, "Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin."

- 232,980
- 40
- 330
- 338

- 77,191
- 7
- 105
- 161
The thread is old and answered, but i thought I'd proceed anyway. It's for completeness and people should know some things about Random in c#.
As for truly random, the best you can ever hope to do is use a "secure Pseudo Random Generator" like salsa20 or RC4 (sort of, sometimes). They pass a barrage of tests where "efficient" adversaries try to distinguish them from random. This comes with certain costs and is probably unnecessary for most uses.
The random class in c# is pretty good most of the time, it has a statically distribution that looks random. However the default seed for random() is the system time. So if you take lots of randoms at the "same time" they are taken with the same seed and will be the same ("random" is completely deterministic, don't let it fool you). Similar system time seeds also may produce similar numbers because of random class's shortcomings. The way to deal with this is to set you own seeds, like
Random random = new Random((int)DateTime.Now.Ticks & (0x0000FFFF + x));
where x is some value you increment if you've created a loop to get a bunch of random numbers, say.
Also with c# random extensionsto your new variable like NextDouble() can be helpful in manipulating the random numbers, in this case crow-baring them into interval (0,1) to become unif(0,1), which happens is a distribution you can plug into stat formulas to create all the distributions in statistics.

- 6,262
- 4
- 36
- 75
-
2Just looking back, it appears that this answer is hinting you use lots of Random objects for lots of random numbers. You don't, you use one and use random.next a lot. For the record I think new Random(Guid.NewGuid().GetHashCode()) is my favorite, although it really doesn't matter. – Nathan Cooper Mar 06 '14 at 08:50
Take a look at using an algorithm like Yarrow or Fortuna with entropy accumulation. The point with these algorithms is that they keep track of entropy as a measure of theoretical information content available for predicting future numbers by knowing the past numbers and the algorithms used to produce them; and they use cryptographic techniques to fold new entropy sources into the number generator.
You'll still need an external source of random data (e.g. hardware source of random numbers), whether that's time of keystrokes, or mouse movement, or hard disk access times, or CPU temperature, or webcam data, or stock prices, or whatever -- but in any case, you keep mixing this information into the entropy pools, so that even if the truly random data is slow or low quality, it's enough to keep things going in an unpredictable fashion.

- 184,598
- 164
- 608
- 970
I was debating building a random number generator based off twitter or one of the other social networking sites. Basically use the api to pull recent posts and then use that to seed a high quality pseudo random number generator. It probably isn't any more effective than randomizing off the timer but seemed like fun. Besides it seems like the best use for most of the stuff people post to twitter.

- 7,168
- 6
- 43
- 66
-
This likely has all the same attack vectors as seeding from a timestamp. – Bob Aman Oct 24 '09 at 02:26
There is no "true" random in computers, everything is based on something else. For some (feasible) ways to generate pseudorandom data, try something such as a pool of the HD temp, CPU temp, network usage (packets/second) and possibly hits/second to the webserver.

- 81
- 1
- 1
- 3
-
`There is no "true" random in computers`, neither on real life. Except if by "random" you mean "something I can't predict for now". – Matthieu Charbonnier Jul 20 '17 at 12:16
Just to clarify everyone saying that there is no True RNG available in C# or on your computer is mistaken. A multi-core processor is inherently a True RNG. Very simply by taking advantage of processor spin you can generate bools that have no discernible pattern. From there you can generate whatever number range you want by using the bools as bits and constructing the number by adding the bits together.
Yes this is magnitudes slower than a purely mathematical solution but a purely mathematical solution will always have a pattern.
public static bool GenerateBoolean()
{
var gen1 = 0;
var gen2 = 0;
Task.Run(() =>
{
while (gen1 < 1 || gen2 < 1)
Interlocked.Increment(ref gen1);
});
while (gen1 < 1 || gen2 < 1)
Interlocked.Increment(ref gen2);
return (gen1 + gen2) % 2 == 0;
}

- 221
- 2
- 6
There is no way to generate truly random numbers with a computer. True randomness requires an external source that monitors some natural phenomenon.
That said, if you don't have access to such a source of truly random numbers you could use a "poor man's" process like this:
- Create a long array (10000 or more items?) of numbers
- Populate the array with current time-seeded random numbers the standard way
- When a random number is required, generate a random index into the array and return the number contained at that position
- Create a new, current time-seeded random number at the array index to replace the number used
This two-step process should improve the randomness of your results somewhat without the need for external input.
Here's a sample library that implements the above-described algorithm in C++: http://www.boost.org/doc/libs/1_39_0/libs/random/random-generators.html

- 79,492
- 20
- 149
- 189
-
@ryeguy That's exactly how it works. Here's a detailed explanation with C++ code: http://www.boost.org/doc/libs/1_39_0/libs/random/random-generators.html – Paul Sasik Aug 05 '09 at 16:51
-
1+1, because this doesn't deserve a negative score. The suggested method may not incerase quality of randomness as much as using a better algorithm would, but it's still a fair point. – Noldorin Aug 05 '09 at 17:35
-
1The question is about true randomness, and this answer inhibits randomness by limiting the randomness to a pool of already chosen random numbers. Also I doubt how this will improve (pseudo) randomness?? – nawfal Dec 14 '12 at 05:49
This code will return you a random number between min
and max
:
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public int RandomNumber(int min, int max)
{
lock (syncLock)
{ // synchronize
return random.Next(min, max);
}
}
Usage:
int randomNumber = RandomNumber(0, 10); // a random number between 1 and 10

- 109,027
- 88
- 289
- 474
-
3Did you read through the entire question? The OP said he knows about the Random class, he is (at this point was since this question is quite old) looking for a way to generate "Truly random numbers". – Jack Jul 27 '12 at 13:47
-
1That's a quote from the OP, basically the numbers generated by the `Random` class are only [Pseudo Random](http://en.wikipedia.org/wiki/Pseudo-random_number). If you read some of the answers in reply to this question you should get a better idea of what the OP means. – Jack Jul 27 '12 at 13:56
-
-
1May not be want the OP wanted, but it's what I wanted, thanks, good idea. – bladefist Sep 10 '12 at 15:22