尽管标题很奇怪,但我想问一个合理的问题:哪个方法生成的数字更随机:Java 的Random()
类Math.random()
还是 C++ 的rand()
?
我听说 PHPrand()
很糟糕,也就是说,如果你映射它的结果,你可以清楚地看到一个模式;可悲的是,我不知道如何用 C++ 或 Java 绘制地图。
另外,只是出于兴趣,C# 呢?
Java 和 C++ 都生成伪随机数,它们是:
老实说,除非您属于其中一类,否则伪随机数生成器就可以了。
Java 还SecureRandom
声称提供加密类的非确定性(我无法评论该论点的真实性),而 C++ 现在具有更广泛的随机数生成能力,而不仅仅是rand()
- 请参阅<random>
详细信息。
特定的操作系统可能会为随机数生成器提供熵源,例如在 Windows 下或在 LinuxCryptGenRandom
下读取。/dev/random
或者,您可以通过使用随机事件(例如用户输入时间)来添加熵。
(a)实际上可能包含不是统计学家或密码学家的其他工作类型的痕迹:-)
java.util.Random
(由 内部使用Math.random()
)使用线性同余生成器,这是一个相当弱的 RNG,但对于简单的事情来说已经足够了。对于重要的应用程序,应该使用java.security.SecureRandom
。
我不认为 C 或 C++ 语言规范禁止使用该算法,rand()
但大多数实现也使用 LCG。C++11 添加了新的 API,可以产生更高质量的随机性。
可以在网上找到一个非常好的文档,由世界范围内的随机数生成器专家之一完成。
文档的第一部分是对测试的描述,除非您真的感兴趣,否则您可以跳过它。从第 27 页开始,有许多生成器的不同测试结果,包括 Java、C++、Matlab、Mathematica、Excel、Boost,...(它们在文本中进行了描述)。
看起来Java的生成器好一点,但两者都不是世界上最好的。C++11 的 MT19937 已经好很多了。
PHP 使用种子。如果种子在两个不同的时间相同,则 rand() 函数将始终输出相同的内容。(例如,这对于令牌来说可能非常糟糕)。我不知道 C++ 和 Java,但没有真正的随机性,这使得质量难以评估。安全性不能依赖这些功能。
我不知道随机数真正随机的任何语言 - 我确信存在这样的事情,但一般来说,它是“你把种子放进去,你就会得到种子给出的序列”。如果你想制作一个简单的“射击”游戏、基本的扑克游戏、家用轮盘赌模拟器等,这很好。但是如果你有钱依赖于真正随机的游戏(例如,你正在给钱基于某些序列的结果)或您的秘密文件依赖于您的随机数,那么您肯定需要一些其他机制来查找随机数。
周围有一些“真正的”随机数生成器。他们不提供种子,因此基于您上次获得的数字的可预测性很低。我并不是说它是零,因为我不确定你是否可以通过以未使用的无线电频率、放射性衰变或任何最新的生成真随机数的方法来采样无线电波来获得它。