Java中的随机数是否真的不可预测?

时间:2012-04-07 14:22:03

标签: java random generator

有一些方法可以在java中生成随机数

其中一个就是:

Random rand=new Random();
int randomInteger=rand.nextInt();

现在我的问题是:我们可以预测下一个随机数吗?


在4个答案之后编辑:

我真正的问题是:

我正在进行蛇游戏(Linux中的半字节),我正在编程蛇移动,现在我想知道是否有可能预测苹果将出现的下一个地方。

有可能吗?

5 个答案:

答案 0 :(得分:5)

你不仅可以预测它,而且绝对可以知道,如果你确切地知道System.currentTimeMillis在调用new Random()时会返回什么。这是因为new Random()new Random(System.currentTimeMillis())的快捷方式,它设置了伪随机生成器的种子。 (好吧,这就是我上次查看来源时所做的事情;文档don't actually say必须使用它。) 如果你知道种子{{1} } 用过的。伪随机生成器是确定性的,如果你知道种子,你就知道序列。 更新:查看Java 6源代码[我没有Java 7源代码],默认种子是在使用时递增的种子编号加上new Random()的组合。所以你需要知道这两个。提高标准。

如果知道System.nanoTime发生System.currentTimeMillis()时的确切值 new Random()使用的种子,那么确实很难来预测下一个值是什么。这就是伪随机生成器的重点。我不会说这是不可能的。真的,真的很难有任何信心。


问题编辑后更新:这是可能的,但是非常非常努力,并且这样做的方式可以让玩家提高他们的分数游戏,我会说你可以忽略它。

答案 1 :(得分:2)

Random类生成的“随机”数字是通过算法生成的,因此实际上是伪随机数。所以是的,从理论上讲,你可以预测下一个数字。知道一个Random产生的数字,或者甚至是一系列数字,都不足以预测下一个数字;您还需要知道Random对象正在使用的种子,并且您需要遵循其伪随机数生成算法。

如果您想要一组可重复的“随机”数字,您可以在创建Random实例时指定自己的种子,例如

Random rand = new Random(1234); // Replace 1234 with any value you'd like

每次使用相同的种子实例化Random时,您将获得相同的数字系列。因此,例如,您可以编写一个小的命令行程序,用一些种子实例化Random并打印它返回的数字列表,然后在代码中使用相同的种子实例化Random。然后,您将知道您的代码将接收哪些数字以及按什么顺序。这对于调试来说非常方便。

答案 2 :(得分:1)

在像计算机这样的确定性设备上可能没有真正随机的数字。但

如果您需要加密安全随机数,请使用SecureRandom:http://docs.oracle.com/javase/6/docs/api/java/security/SecureRandom.html

随机使用确定性算法:

  

如果使用相同的种子创建了两个Random实例,并且为每个实例创建了相同的方法调用序列,则它们将生成并返回相同的数字序列。

http://docs.oracle.com/javase/6/docs/api/java/util/Random.html#Random

答案 3 :(得分:0)

基本上,如果您知道随机数生成器的种子,您可以确定地预测整个序列。如果不这样做,无论你产生多少数字,都无法准确预测下一个数字。

请注意,如果您依赖于无法预测安全性的数字,则应使用java.secure.SecureRandom而不是java.util.Random

答案 4 :(得分:0)

当其他人回答这个问题时,如果您知道起始种子,则可以预测java.util.Random的随机性。

如果您正在使用类似Linux的系统,请查看这些特殊文件/dev/randomdev/urandom。据说这些文件的读取会返回“更好”的随机数,随机性取决于键盘活动,鼠标移动和其他一些奇特因素。

有关详细信息,请参阅此Wikipedia 页面。此页面还说明Windows中存在等效的API。