12 Цитирование уникальных случайных чисел в Java

Я работал над приложением, где нам нужно сгенерировать уникальный номер, и практически не было предопределенных ограничений, поэтому использовал java-генератор UUD и работал нормально. Теперь нам даны новые требования для генерации 12 цифр уникального случайного числа.

Может ли кто-нибудь указать мне какой-то хороший способ/алгоритм для достижения этого, поскольку я не вижу никакой возможности в генерации UUID номера.

Заранее спасибо

Ответы

Ответ 1

Сгенерируйте каждую цифру, вызывая random.nextInt. Для уникальности вы можете отслеживать случайные числа, которые вы использовали до сих пор, сохраняя их в наборе и проверяя, содержит ли набор число, которое вы генерируете каждый раз.

public static long generateRandom(int length) {
    Random random = new Random();
    char[] digits = new char[length];
    digits[0] = (char) (random.nextInt(9) + '1');
    for (int i = 1; i < length; i++) {
        digits[i] = (char) (random.nextInt(10) + '0');
    }
    return Long.parseLong(new String(digits));
}

Ответ 2

(long)Math.random()*1000000000000L

Но есть вероятность столкновения

Почему бы не использовать последовательность? Начиная с 100 000 000 000 до 999 999 999 999? сохранить запись последнего сгенерированного номера.


Изменить: спасибо bence olah, я исправил жуткую ошибку

Ответ 3

Улучшено проверенное решение с помощью StringBuilder():

public static long generateRandom() {
    Random random = new Random();
    StringBuilder sb = new StringBuilder();

    // first not 0 digit
    sb.append(random.nextInt(9) + 1);

    // rest of 11 digits
    for (int i = 0; i < 11; i++) {
        sb.append(random.nextInt(10));
    }

    return Long.valueOf(sb.toString()).longValue();
}

Ответ 4

В последнее время у меня было очень похожее требование и придумал следующее:

import com.google.inject.Provider;
import java.security.SecureRandom;
import org.apache.commons.codec.binary.Base64;

public final class SecureKeyProvider {

    private final SecureRandom rng;
    private final int entropyBytes;

    public SecureKeyProvider(int entropyBytes) {
        this.rng = new SecureRandom();
        this.entropyBytes = entropyBytes;
    }

    public String get() {

        /* SecureRandom documentation does not state if it thread-safe,
         * therefore we do our own synchronization. see
         *
         * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6498354
         */

        synchronized (this.rng) {
            final byte[] random = new byte[this.entropyBytes];
            rng.nextBytes(random);
            return Base64.encodeBase64URLSafeString(random);
        }
    }

}

Он использует кодировщик Base64 из общих ресурсов apache, который у меня был в моем проекте. Может быть, вы хотите заменить его чем-то простым, но в противном случае он выполняет эту работу.

Ответ 5

Random random = new Random();
Math.round(random.nextFloat() * Math.pow(10,12))

Ответ 6

Вы можете попробовать это. Это генерирует случайное число для 12 цифр. Вы должны указать диапазоны.

    package test;
import java.util.Random;
/** Generate random integers in a certain range. */
public final class RandomRange {
  public static final void main(String... aArgs){
    log("Generating random integers in the range 100000000000..999999999999.");
    long START = 100000000000l;
    long END = 999999999999l;
    Random random = new Random();
    for (int idx = 1; idx <= 10; ++idx){
      showRandomInteger(START, END, random);
    }
    log("Done.");
  }

  private static void showRandomInteger(long aStart, long aEnd, Random aRandom){
    if ( aStart > aEnd ) {
      throw new IllegalArgumentException("Start cannot exceed End.");
    }
    //get the range, casting to long to avoid overflow problems
    long range = (long)aEnd - (long)aStart + 1;
    // compute a fraction of the range, 0 <= frac < range
    long randomNumber = (long)(range * aRandom.nextDouble());
    System.out.println(" fraction... "+randomNumber);
  }

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

Ответ 7

Вы можете попытаться получить UUIDs LSB и MSB наполовину как longs и преобразовать их в число.

Ответ 8

Я бы подумал о простом хэшировании System.nanoTime(), предполагая, что вы не возражаете против 1 из 1 миллиарда шансов столкновения хэшей.

Ответ 9

long number = 0l;
Random rand = new Random();
number = (rand.nextInt(1000000)+1000000000l) * (rand.nextInt(900)+100);