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);