Использование безопасного случайного для генерации длинного номера

Я засеял мой безопасный случайный объект длинным числом. Теперь я хочу извлечь еще один длинный номер. Но существует только функция, называемая 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

Результат для кода Питера Лоури: (Использование безопасного случайного)

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

Они превосходят то же самое. Как вы можете получить разные цифры? Это результат, который я получаю после использования второго обновления Peter Lawrey (я использую операционную систему Windows, и он, кажется, использует другую операционную систему, которая создала путаницу)

******** appears to produce the same values with the same seed
The default PRNG on this system is ********
4 ответа

Пересмотренный снова, это правильный ответ! (и я должен следовать моему собственному совету и внимательно прочитать документацию)

Является этим, что вы используете? Если это так, он расширяет Random, поэтому имеет унаследованный метод nextLong(). Поскольку он переопределяет next(), все типичные случайные методы будут использовать метод SecureRandom PRNG.

(см. комментарии, почему мой второй ответ неверен или, скорее, не нужен)

Я бы предложил создать длинный, просто составив его из следующих 8 байтов или двух ints (возвращенных следующим). Нет проблем с этим, и я не вижу причин, по которым вы не смогли бы коснуться всех длинных значений (подумайте, что любая из двух 32-битных половинок может иметь значения от 0 до 2 ^ 32, с равными вероятность) или почему один был бы более вероятным, чем другой (что означало бы его не псевдослучайным).Забастовкa >

Я не совсем понимаю, почему документация Random указывает это ограничение для nextLong(), но я считаю, что это ограничение используемого линейного алгоритма (я думаю, что линейные алгоритмы имеют намного более короткий цикл, т.е. когда они начинают повторяться цифры - чем современные ПРНГ). Я думаю, что стоит потратить внимание на обмен криптографического стека на любопытство.


SecureRandom расширяет Random и Random имеет метод nextLong(): http://docs.oracle.com/javase/6/docs/api/java/util/Random.html#nextLong%28%29


Примечание. При использовании Random, заданное семя всегда будет давать одинаковые результаты. С SecureRandom этого не произойдет. Семя просто добавляет случайности.

Вы когда-нибудь пользовались безопасностью? Вся суть семени заключается в том, чтобы произвести одно и то же количество чисел. Это также относится к безопасному случайному. Два безопасных случайных числа, засеянных одним и тем же значением, производят одну и ту же последовательность случайных чисел.

public static void main(String... args) throws NoSuchProviderException, NoSuchAlgorithmException {
 testRNG("NativePRNG");
 testRNG("********");
 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
******** appears to produce the same values with the same seed
The default PRNG on this system is NativePRNG

перейдите и попробуйте сначала

Хороший совет, но просто попытка не всегда дает вам целый ответ в этом случае.


BigInteger randomNumber = new BigInteger(numBits, random);

licensed under cc by-sa 3.0 with attribution.