Why use the C# class System.Random at all instead

2019-01-04 11:40发布

Why would anybody use the "standard" random number generator from System.Random at all instead of always using the cryptographically secure random number generator from System.Security.Cryptography.RandomNumberGenerator (or its subclasses because RandomNumberGenerator is abstract)?

Nate Lawson tells us in his Google Tech Talk presentation "Crypto Strikes Back" at minute 13:11 not to use the "standard" random number generators from Python, Java and C# and to instead use the cryptographically secure version.

I know the difference between the two versions of random number generators (see question 101337).

But what rationale is there to not always use the secure random number generator? Why use System.Random at all? Performance perhaps?

13条回答
做自己的国王
2楼-- · 2019-01-04 12:10

Speed and intent. If you're generating a random number and have no need for security, why use a slow crypto function? You don't need security, so why make someone else think that the number may be used for something secure when it won't be?

查看更多
一夜七次
3楼-- · 2019-01-04 12:10

Not everyone needs cryptographically secure random numbers, and they might benefit more from a speedier plain prng. Perhaps more importantly is that you can control the sequence for System.Random numbers.

In a simulation utilizing random numbers you might want to recreate, you rerun the simulation with the same seed. It can be handy for tracking bugs when you want to regenerate a given faulty scenario as well - running your program with the exact same sequence of random numbers that crashed the program.

查看更多
走好不送
4楼-- · 2019-01-04 12:15

Different needs call for different RNGs. For crypto, you want your random numbers to be as random as possible. For Monte Carlo simulations, you want them to fill the space evenly and to be able to start the RNG from a known state.

查看更多
Ridiculous、
5楼-- · 2019-01-04 12:16

System.Random is much more performant since it does not generate cryptographically secure random numbers.

A simple test on my machine filling a buffer of 4 bytes with random data 1,000,000 times takes 49 ms for Random, but 2845 ms for RNGCryptoServiceProvider. Note that if you increase the size of the buffer you are filling, the difference narrows as the overhead for RNGCryptoServiceProvider is less relevant.

查看更多
贪生不怕死
6楼-- · 2019-01-04 12:18

Random is not a random number generator, it is a deterministic pseudo-random sequence generator, which takes its name for historical reasons.

The reason to use System.Random is if you want these properties, namely a deterministic sequence, which is guaranteed to produce the same sequence of results when initialized with the same seed.

If you want to improve the "randomness" without sacrificing the interface, you can inherit from System.Random overriding several methods.

Why would you want a deterministic sequence

One reason to have a deterministic sequence rather than true randomness is because it is repeatable.

For example, if you are running a numerical simulation, you can initialize the sequence with a (true) random number, and record what number was used.

Then, if you wish to repeat the exact same simulation, e.g. for debugging purposes, you can do so by instead initializing the sequence with the recorded value.

Why would you want this particular, not very good, sequence

The only reason I can think of would be for backwards compatibility with existing code which uses this class.

In short, if you want to improve the sequence without changing the rest of your code, go ahead.

查看更多
孤傲高冷的网名
7楼-- · 2019-01-04 12:23

Apart from the speed and the more useful interface (NextDouble() etc) it is also possible to make a repeatable random sequence by using a fixed seed value. That is quite useful, amongst others during Testing.

Random gen1 = new Random();     // auto seeded by the clock
Random gen2 = new Random(0);    // Next(10) always yields 7,8,7,5,2,....
查看更多
登录 后发表回答