Java安全随机数中的重复随机数

时间:2014-07-03 15:02:50

标签: java random

我期待来自以下Callable的唯一随机数:

public class UniqueGenerator implements Callable<Integer> {

    private static SecureRandom rnd;

    static {
        try {
            rnd = SecureRandom.getInstance("SHA1PRNG");
            rnd.setSeed(UUID.randomUUID().toString().getBytes());
        } catch (NoSuchAlgorithmException e) {
        }
    }

    @Override
    public Integer call() throws Exception {
        return rnd.nextInt();

    }
}

然而,从1,000,000次执行此方法,我永远不会获得1,000,000个唯一整数。 有什么方法可以得到理想的结果吗? 在尝试生成唯一的整数时我犯了什么错误?

4 个答案:

答案 0 :(得分:3)

如果您想要1,000,000个唯一随机整数,请创建一个ArrayList,其中Integer个对象从0到999,999,然后使用您的SecureRandom对象随机播放该列表:

Collections.shuffle(cards, secureRandom);

然后根据需要使用整数,如果列表为空,则重新创建列表。

答案 1 :(得分:1)

当然,他们不会是独一无二的。它们是随机的。对于psuedo随机数生成器来说,吐出与它已经生成的数字相同的数字是非常完美的。如果你运行它足够长,比如2 ^ 32次,你就不会得到2 ^ 32个唯一数字。许多数字将重复出现。如果你想要独特的随机值,UUID是一个好的开始(虽然它们不能保证是唯一的 - 这些都是出于实用目的。)

答案 2 :(得分:1)

如果您想要随机排列的百万个唯一数字,我会使用Collections.shuffle()。例如,

List<Integer> al = new ArrayList<>();
for (int i = 0; i < 1000 * 1000; i++) {
  al.add(i);
}
Collections.shuffle(al);
// al contains 1,000,000 numbers in random order.

答案 3 :(得分:1)

生日悖论。您的整数有4294967296可能的值。为简单起见,让我们说40亿。您正在生成100万随机整数。这意味着这些随机整数中的每一个在4000上大约有1次机会随机地具有与另一个相同的值。那个缝很小,但它是一个整数,你有999999其他情况来测试。这背后的数学有点复杂,但我们只是说重复的几率几乎是1/1。

http://en.wikipedia.org/wiki/Birthday_problem