带种子的随机数

时间:2010-08-27 11:02:20

标签: java

参考:link text

我无法理解以下内容,有人能为我提供以下声明的一些示例吗?

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

6 个答案:

答案 0 :(得分:12)

因为你问了一个例子:

import java.util.Random;
public class RandomTest {
    public static void main(String[] s) {
        Random rnd1 = new Random(42);
        Random rnd2 = new Random(42);

        System.out.println(rnd1.nextInt(100)+" - "+rnd2.nextInt(100));
        System.out.println(rnd1.nextInt()+" - "+rnd2.nextInt());
        System.out.println(rnd1.nextDouble()+" - "+rnd2.nextDouble());
        System.out.println(rnd1.nextLong()+" - "+rnd2.nextLong());
    }
}

无论您使用多少平台或使用的Java版本,两个Random实例都将始终具有相同的输出,无论您运行的频率如何:

30 - 30
234785527 - 234785527
0.6832234717598454 - 0.6832234717598454
5694868678511409995 - 5694868678511409995

答案 1 :(得分:8)

随机生成器 deterministic 。给定Random的相同输入和Random中方法的相同用法,即使在不同机器上的不同运行中,返回到程序的伪随机数序列也是相同的。

这就是为什么它是伪随机的 - 返回的数字在行为上在统计上类似于随机数,除非它们可以被可靠地预测。真随机数是不可预测的。

答案 2 :(得分:3)

Random类基本上是一个伪随机数生成器(也称为确定性随机位生成器),它生成一个近似于随机数属性的数字序列。它通常不是随机的,而是确定性的,因为它可以由生成器中的小随机状态确定(例如seed)。由于确定性,如果两个方法和种子序列在2个生成器上相同,则可以生成相同的结果。

答案 3 :(得分:2)

如果相同的起始条件(种子)和相同的操作顺序,数字不是真正随机的,将生成相同的数字序列。这就是为什么使用基本的随机类作为任何加密或安全相关代码的一部分并不是一个好的原因,因为攻击者可能会弄清楚正在生成哪个序列并预测未来的数字。

对于发出非确定性值的随机数生成器,请查看SecureRandom

有关详细信息,请参阅维基百科上的Random number generation, Computational methods

答案 4 :(得分:1)

这意味着当您创建Random对象时(例如,在程序开头),您可能希望以新种子开始。大多数人选择与时间相关的值,例如刻度数。

如果你想调试你的程序,那么数字序列在同一种子上是相同的这一事实实际上非常方便:确保你记录种子值,如果出现问题,你可以在调试器中重启程序相同的种子价值。这意味着您可以完全重放场景。如果您(可以)使用真正的随机数生成器,这将是不可能的。

答案 5 :(得分:0)

使用相同的种子值,Random的单独实例将返回/生成相同的随机数序列;更多关于这里: http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Tech/Chapter04/javaRandNums.html

Ruby示例:

class LCG; def initialize(seed=Time.now.to_i, a=2416, b=374441, m=1771075); @x, @a, @b, @m = seed % m, a, b, m; end; def next(); @x = (@a * @x + @b) % @m; end; end

irb(main):004:0> time = Time.now.to_i
=> 1282908389

irb(main):005:0> r = LCG.new(time)
=> #<LCG:0x0000010094f578 @x=650089, @a=2416, @b=374441, @m=1771075>
irb(main):006:0> r.next
=> 45940
irb(main):007:0> r.next
=> 1558831
irb(main):008:0> r.next
=> 1204687
irb(main):009:0> f = LCG.new(time)
=> #<LCG:0x0000010084cb28 @x=650089, @a=2416, @b=374441, @m=1771075>
irb(main):010:0> f.next
=> 45940
irb(main):011:0> f.next
=> 1558831
irb(main):012:0> f.next
=> 1204687

基于值a / b / m,给定种子的结果将是相同的。这可以用于在两个地方生成相同的“随机”数字,并且双方都可以依赖于获得相同的结果。这对加密很有用;虽然很明显,但这种算法在加密方面并不安全。