How do the “random” generators in different langua

2019-02-21 19:14发布

问题:

Despite the weird title, I wish to ask a legitimate question: which method's generated numbers are more random: Java's Random() class or Math.random(), or C++'s rand()?

I've heard that PHP's rand() is quite bad, i.e. if you map its results you can clearly see a pattern; sadly, I don't know how to draw a map in C++ or Java.

Also, just out of interest, what about C#?

回答1:

Both Java and C++ generate pseudo-random numbers which are either:

  • adequate to the task for anyone who isn't a statistician or cryptographer (a); or
  • woefully inadequate to those two classes of people.

In all honesty, unless you are in one of those classes, pseudo-random number generators are fine.

Java also has SecureRandom which purports to provide crypto-class non-determinism (I can't comment on the veracity of that argument) and C++ now has a much wider variety of random number generation capability than just rand() - see <random> for details.

Specific operating systems may provides sources of entropy for random number generators such as CryptGenRandom under Windows or reading /dev/random under Linux. Alternatively, you could add entropy by using random events such as user input timing.


(a) May actually contain traces of other job types that aren't statistician or cryptographer :-)



回答2:

java.util.Random (which is used internally by Math.random()) uses a Linear congruential generator, which is a rather weak RNG, but enough for simple things. For important applications, one should use java.security.SecureRandom instead.

I don't think the C or C++ language specifications proscribe the algorithm to use for rand() but most implementations use a LCG as well. C++11 has added new APIs that yield higher-quality randomness.



回答3:

There is a very good document that can be found on the web, done by one of the worldwide experts in random number generators.

Here is the document

The first part of the document is a description of the tests, which you might skip unless your really interested. From page 27, there are the results of the different tests for many generators, including Java, C++, Matlab, Mathematica, Excel, Boost,... (They are described in the text).

It seems that the generator of Java is a bit better, but both are not among the best in the world. The MT19937 from C++11 is already much better.



回答4:

PHP uses a seed. If the seed is the same at two different times, the rand() function will ALWAYS output the same thing. (Which can be quite bad for tokens for example). I don't know for C++ and Java, but there's no true randomness, which makes quality difficult to evaluate. Security musn't rely on such functions.



回答5:

I'm not aware of any language where random numbers are truly random - I'm sure such a thing exists, but generally, it's "You stick a seed in, and you get the sequence that seed gives". Which is fine if you want to make a simple 'shootem-up' game, basic poker-game, roulette simulator for home use, etc. But if you have money relying on the game being truly random (e.g., you are giving out money based on the results of certain sequences) or your secret files are relying on your random numbers, then you will definitely need some other mechanism for finding random numbers.

And there are some "true" random number generators around. They do not provide a seed, so predictability based on what number(s) you got last time is low. I'm not saying it's zero, because I'm not sure you can get that even from sampling radio waves at an unused radio frequency, radioactive decay or whatever the latest method of genearing true random numbers is.



标签: java c++ random