Является ли RandomStringUtils.randomAlphanumeric(30) допустимой стратегией GUID?

Мне нужен генератор случайных строк, который генерирует буквенно-цифровую строку для использования в качестве уникального ключа в распределенной системе, длина которого 30 символов или менее. Он не может содержать никаких специальных символов.

Будет ли для этого работать RandomStringUtils # randomAlphanumeric?

Основная реализация использует java.util.Random,

Набор уникальных ключей, вероятно, будет менее 100 миллиардов, и система должна иметь возможность обрабатывать до 1000 записей в секунду.

Как я могу доказать, что эта стратегия имеет достаточно низкую вероятность столкновения, чтобы работать в качестве генератора первичного ключа?

2 ответа

java.util.Random реализует алгоритм LCG, и его период составляет 2^48 чисел, поэтому RandomStringUtils будет так же хорош, как и эта реализация, и 100 миллиардов 30-символьных строк потребуют ~ 1% от 2^48 случайных элементов.

Обратите внимание, что java.util.Random не является криптографически безопасным, поэтому, учитывая некоторые идентификаторы GUID, можно вывести следующий, поэтому я бы использовал другую реализацию, которая использует криптографически безопасный генератор случайных чисел (например, java.util.SecureRandom).

Случайный не уникален. Использование генерации случайных чисел для получения "уникальных" значений приводит к проблеме дня рождения https://en.wikipedia.org/wiki/Birthday_attack. Это превращает вероятность 1 в 2^48 в вероятность 1 в 2^24, что приведет к тому, что вы попадете быстрее, чем вы думаете. Использовать UUID; они разработаны, чтобы быть универсально уникальными.

32 символа:

UUID.randomUUID().toString.replace("-","")

22 персонажа:

UUID uuid = UUID.randomUUID();
String uuidStr = Base64.encodeBase64URLSafeString(ByteBuffer.wrap(new byte[16])
    .putLong(uuid.getMostSignificantBits())
    .putLong(uuid.getLeastSignificantBits())
            .array()).replace("=", "");

Почему вы не хотите использовать java.util.UUID учебный класс? Возвращает случайный UUID из 32-битных символов String. Пример реализации:

import java.util.UUID;

public class GenerateUUID {

   public static final void main(String... aArgs){
     //generate random UUIDs
     UUID idOne = UUID.randomUUID();
     UUID idTwo = UUID.randomUUID();
     log("UUID One: " + idOne);
     log("UUID Two: " + idTwo);
   }

   private static void log(Object aObject){
     System.out.println(String.valueOf(aObject));
   }
} 
Другие вопросы по тегам