2

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

其中之一是:

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

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


在4个答案后编辑:

我真正的问题是:

我正在开发一个蛇游戏(Linux 中的 nibbles),我正在对蛇进行编程以使其移动,现在我想知道是否有可能预测苹果将出现的下一个位置。

可能吗?

4

5 回答 5

5

您不仅可以预测它,而且绝对知道它,如果您确切知道System.currentTimeMillis调用new Random(). 这是因为new Random()是 的快捷方式new Random(System.currentTimeMillis()),它设置了伪随机生成器的种子。(嗯,这就是我上次查看源代码时所做的;文档实际上并没有说它必须使用它。) 如果您知道使用的种子new Random()。伪随机生成器是确定性的,如果你知道种子,你就知道序列。更新:查看 Java 6 源代码 [我手边没有 Java 7 源代码],默认种子是使用时递增的种子编号的组合,加上System.nanoTime. 所以你需要知道这两个。提高标准。

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


问题编辑后更新:这是可能的,但非常非常困难,而且就这样做的方式而言,可以让玩家提高他们在游戏中的得分,我想说你可以忽略它。

于 2012-04-07T14:25:53.463 回答
2

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

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

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

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

于 2012-04-07T14:28:35.290 回答
1

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

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

Random 使用确定性算法:

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

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

于 2012-04-07T14:30:17.353 回答
0

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

请注意,如果您依赖不可预测的数字来保证安全,您应该使用java.secure.SecureRandom而不是java.util.Random.

于 2012-04-07T14:31:32.820 回答
0

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

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

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

于 2012-04-07T17:42:14.710 回答