我在阅读 Math.random() 的 java 文档时发现,随机数实际上只是伪随机数。
是否有一个库(特别是 Java),能够根据环境温度、CPU 温度/电压等随机变量生成随机数呢?
RANDOM.ORG是一个通过大气噪音生成随机数的真正随机数服务。
与其进行交互的Java库可以在这里找到: http://sourceforge.net/projects/trng-random-org/
你的问题存在歧义,这导致答案非常分散。
如果你正在寻找一种依赖于系统随机源的随机实现(我猜你是这样的),那么java.security.SecureRandom可以达到这个目的。Sun安全提供程序在你的java.security文件中的默认配置如下:
#
# Select the source of seed data for SecureRandom. By default an
# attempt is made to use the entropy gathering device specified by
# the securerandom.source property. If an exception occurs when
# accessing the URL then the traditional system/thread activity
# algorithm is used.
#
# On Solaris and Linux systems, if file:/dev/urandom is specified and it
# exists, a special SecureRandom implementation is activated by default.
# This "NativePRNG" reads random bytes directly from /dev/urandom.
#
# On Windows systems, the URLs file:/dev/random and file:/dev/urandom
# enables use of the Microsoft CryptoAPI seed functionality.
#
securerandom.source=file:/dev/urandom
如果你真的想要用更加随机的方式来覆盖这个值,可以通过更改此属性或使用另一个SecureRandom来完成。例如,你可以使用支持HSM模块的JCE提供者,如nCipher nShield自带的PRNG,或者在讨论中提到的其他解决方案。快速而不精确:
public static int generateRandom() throws IOException
{
int num = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
for (int i = 0 ; i < Integer.SIZE ; i++)
{
System.out
.println("Flip a fair coin. Enter h for heads, anything else for tails.");
if (br.readLine().charAt(0) == 'h')
{
num += Math.pow(2, i);
}
}
return num;
}
SecureRandom
即可。 - maaartinus由于访问这些随机数据源需要某种形式的硬件访问,因此使用纯Java无法编写可移植的库。
但是,您可以尝试编写平台相关代码以读取平台的随机数据源。例如,对于Linux(以及可能也适用于其他类Unix系统),可以使用/dev/random
。
另外,请查看SecureRandom类,它可能已经具备您想要的功能。
Java加密架构需要具有密码学强度的随机数。其中包含@saua提到的SecureRandom类。
没有真正的随机数生成器,因为它们都依赖于确定性过程来计算随机数,所以无论生成的数字看起来是否遵循真正的随机分布,它们可能是隐藏的 - 并且非常复杂的 - 模式的一部分,因此它们是伪随机的。 然而,您可以实现自己的随机数生成器,有几种不错的、计算廉价的方法可以在C语言数值计算方法(第二版) - 第7章中阅读。 希望对您有所帮助
对于大多数情况而言,伪随机数已经足够使用。如果你只需要一个简单的随机数,例如“30%的时间执行此操作”,那么使用时间戳作为种子即可。如果需要安全随机数,例如洗牌一副牌,你需要更加仔细地选择种子,存在一些良好的来源以创建安全种子。
使用种子的原因是为了能够"重现"由算法生成的相同随机数序列。非常好的应用场景就是在进行随机模拟某些实验时,你想要重复特定实验,然后你只需使用相同的种子。
如果需要比Java自带的更好的PRNG,请看一下梅森旋转算法。