Подтвердить что ты не робот

Генерировать 8-байтовое число в Java

Я немного смущен, как это сделать. Я знаю, что я могу использовать случайный класс для генерации случайных чисел, но я не знаю, как указать и сгенерировать 8-байтовое число?

Спасибо, Вук

4b9b3361

Ответ 1

Следует отметить, что класс java.util.Random использует 48-битное семя, поэтому не все 8-байтовые значения (последовательности из 64 бит) могут быть сгенерированы с использованием этого класса. Из-за этого ограничения я предлагаю вам использовать SecureRandom и nextBytes в этой ситуации.

Использование довольно похоже на решение java.util.Random.

SecureRandom sr = new SecureRandom();
byte[] rndBytes = new byte[8];
sr.nextBytes(rndBytes);

Вот почему 48-битное семя недостаточно:

  • Класс Random реализует псевдослучайный генератор, что означает, что он детерминирован.
  • Текущее "состояние" Random определяет будущую последовательность бит.
  • Так как он имеет 2 48 состояния, он не может иметь более 2 48 возможных будущих последовательностей.
  • Так как 8-байтовое значение имеет 2 64 различные возможности, некоторые из этих возможностей никогда не будут прочитаны из объекта Random.

На основе @Peter Lawreys отличный ответ (он заслуживает большего внимания!): Вот решение для создания java.util.Random с 2 и раз; 48-битное семя. То есть экземпляр java.util.Random, способный генерировать все возможные long s.

class Random96 extends Random {
    int count = 0;
    ExposedRandom extra48bits;

    class ExposedRandom extends Random {
        public int next(int bits) {    // Expose the next-method.
            return super.next(bits);
        }
    }

    @Override
    protected int next(int bits) {
        if (count++ == 0)
            extra48bits = new ExposedRandom();
        return super.next(bits) ^ extra48bits.next(bits) << 1;
    }
}

Ответ 2

Я согласен с точкой @aioobe о Random, используя 48-битное семя. SecureRandom - лучшее решение. Однако, чтобы ответить на вопросы OP о том, как использовать класс Random и по-прежнему допускать всевозможные 8-байтовые значения, нужно время reset посеять.

int counter = 0;
Random rand = new Random();
Random rand2 = new Random();

if (++counter == 0) rand = new Random(); // reset every 4 billion values.

long randomLong = rand.nextLong() ^ rand2.nextLong() << 1;

Случайный разрешает только последовательность из 2 ^ 47 длинных значений. Используя два случайных генератора, которые продолжают прыгать в последовательности, вы получаете два возможных значения 2 ^ 47 * 2 ^ 47. Использование < 1 заключается в том, чтобы избежать воздействия наличия обоих рандом с одним и тем же семенем (в этом случае ^ будет производить 0 для 4 миллиардов значений подряд)

Ответ 3

Это можно сделать либо с байтовым массивом длиной 8:

byte[] byteArray = new byte[8];    
random.nextBytes(byteArray);

или с переменной типа long (которая представляет 8-байтовые номера):

long randomLong = random.nextLong();

Ответ 4

Тип long представляет собой 8-байтовое целое число со знаком, поэтому Random.nextLong() похоже делает то, что вы хотите. Или если вам нужен массив байтов в качестве результата:

byte[] result = new byte[8];
Random.nextBytes(result);

Ответ 5

Небольшая настройка из кода здесь:

import java.util.Random;

/** Generate 10 random integers in the range 0..99. */
public final class RandomByte {

  public static final void main(String... aArgs){
    log("Generating 10 random integers in range 0..255.");

    //note a single Random object is reused here
    Random randomGenerator = new Random();
    for (int idx = 1; idx <= 10; ++idx){
      int randomInt = randomGenerator.nextInt(256);
      // int randomInt = randomGenerator.nextBytes(256);
      log("Generated : " + randomInt);
    }

    log("Done.");
  }

  private static void log(String aMessage){
    System.out.println(aMessage);
  }
}

Дальнейшее чтение: Math.random() против Random.nextInt(int)