使用安全随机生成一个长号

时间:2012-03-10 09:34:58

标签: java random

我用长号播种了我的安全随机对象。现在我想提取另一个长数字。但是只有一个名为nextBytes(byte[] b)的函数可以随机byte[]

有没有办法得到一个长号?

SecureRandom ranGen1 = new SecureRandom();
   ranGen1.setSeed(1000);
   SecureRandom ranGen2 = new SecureRandom();
   ranGen2.setSeed(1000);
   byte[] b1= new byte[3];
   byte[] b2=new byte[3];
   ranGen1.nextBytes(b1);
   ranGen2.nextBytes(b2);
   int a1=b1[0];
   int a2=b1[1];
   int a3=b1[2];

   int c1=b2[0];
   int c2=b2[1];
   int c3=b2[2];

   System.out.println(a1+", "+a2+", "+a3);//genearated by ranGen1
   System.out.println(c1+", "+c2+", "+c3);//generated by ranGen2

   System.out.println(ranGen1.nextLong());//genearated by ranGen1

System.out.println(ranGen2.nextLong()); //由ranGen2生成

结果:

4, -67, 69
4, -67, 69

   -3292989024239613972  //this is using nextLong()
-3292989024239613972 

Peter Lawrey的代码输出:(使用安全随机)

-7580880967916090810 -7580880967916090810
7364820596437092015 7364820596437092015
6152225453014145174 6152225453014145174
6933818190189005053 6933818190189005053
-2602185131584800869 -2602185131584800869
-4964993377763884762 -4964993377763884762
-3544990590938409243 -3544990590938409243
8725474288412822874 8725474288412822874
-8206089057857703584 -8206089057857703584
-7903450126640733697 -7903450126640733697

他们是相同的。你怎么能得到不同的数字?

这是我在使用Peter Lawrey的第二次更新后得到的输出(我正在使用Windows操作系统,他似乎正在使用其他一些操作系统造成混乱)

SHA1PRNG appears to produce the same values with the same seed
The default PRNG on this system is SHA1PRNG

4 个答案:

答案 0 :(得分:5)

再次修改,这是正确的答案! (我应该遵循自己的建议并更仔细地阅读文档)

this您使用的是什么?如果是这样,它会扩展Random,因此它具有继承的nextLong()方法。当它覆盖next()时,所有典型的Random方法都将使用SecureRandom PRNG方法。

(参见评论为什么我的第二个答案是错误的......或者更不必要)

<击> 我建议通过从接下来的8个字节或两个整数(由下一个返回)中编写它来创建一个long。这样做没有问题,我看不出为什么你不能触及所有长值的任何原因(认为两个32位半部分中的任何一个都可以具有从0到2 ^ 32的值,具有相同的值概率)或为什么一个比另一个更可能(这意味着它不是伪随机的)。

我不完全理解为什么Random文档表明对nextLong()的限制,但我认为它是它使用的线性算法的限制(我认为线性算法的周期要短得多 - 即当它们开始重复时数字 - 比现代的PRNGs)。我认为值得在加密堆栈交换中探索好奇心。

答案 1 :(得分:2)

SecureRandom扩展了Random,而Random有一个nextLong()方法:http://docs.oracle.com/javase/6/docs/api/java/util/Random.html#nextLong%28%29

答案 2 :(得分:2)

注意:使用Random,给定的种子将始终产生相同的结果。使用SecureRandom它不会。种子只会增加随机性。

  

你有没有随机使用安全?种子的全部意义在于产生相同的数字序列。安全随机也是如此。两个用相同值接种的安全随机数产生相同的随机数序列。

public static void main(String... args) throws NoSuchProviderException, NoSuchAlgorithmException {
    testRNG("NativePRNG");
    testRNG("SHA1PRNG");
    System.out.println("The default PRNG on this system is " + new SecureRandom().getAlgorithm());
}

private static void testRNG(String prng) throws NoSuchAlgorithmException, NoSuchProviderException {
    SecureRandom sr1 = SecureRandom.getInstance(prng, "SUN");
    SecureRandom sr2 = SecureRandom.getInstance(prng, "SUN");
    sr1.setSeed(1);
    sr2.setSeed(1);
    for (int i = 0; i < 10; i++) {
        if (sr1.nextLong() != sr2.nextLong()) {
            System.out.println(prng + " does not produce the same values with the same seed");
            return;
        }
    }
    System.out.println(prng + " appears to produce the same values with the same seed");
}

打印

NativePRNG does not produce the same values with the same seed
SHA1PRNG appears to produce the same values with the same seed
The default PRNG on this system is NativePRNG
  

先试试吧

很好的建议,但在这种情况下,尝试它并不总是能给你完整的答案。

答案 3 :(得分:1)

BigInteger randomNumber = new BigInteger(numBits, random);