2016-09-30 2 views
10

Я пытаюсь понять преимущества использования UUID.randomUUID() над генератором SecureRandom, поскольку в первом случае используется securerandom внутри.UUID.randomUUID() vs SecureRandom

+0

В зависимости от того, что вы пытаетесь сделать. Если вам нужны UUID, используйте 'UUID.randomUUID()'. Если вам нужна ваша случайность в какой-либо другой форме, используйте «SecureRandom» напрямую. –

+4

Это немного странно сравнивать их, как если бы они были взаимозаменяемыми. Они делают две разные вещи. 'SecureRandom' - генератор случайных чисел. 'UUID.randomUUID()' генерирует 'UUID', который не является случайным числом. – Jesper

+0

В чем проблема? 'UUID' представляет собой особый тип идентификатора с определенным форматом, тогда как' SecureRandom' просто «генерирует случайные числа». Это разные вещи. – Thomas

ответ

0

UUID не является случайным числом: это универсальный уникальный идентификатор. Вы можете быть уверены, что никто не может генерировать одну и ту же шестнадцатеричную строку.

Случайное число - это еще одна история: это не шестнадцатеричная строка, и она не является универсальной.

Более эффективный и законченный генератор UUID предоставляется this library.

+4

«Вы можете быть уверены, что никто не может генерировать одну и ту же шестнадцатеричную строку». - это может ввести в заблуждение: вы можете генерировать один и тот же uuid, но если следовать правилам, очень маловероятно, что это произойдет. – Thomas

+1

Теоретически вы можете столкнуться, но это очень низкая вероятность: https://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates – uoyilmaz

+0

Если вы хотите, чтобы реальный универсальный уникальный идентификатор и секретность этого значения не важны (потому что это легко предсказать) ** UUID типа 1 **, безусловно, уникален и [относительный класс Java] (https://docs.oracle.com/javase/8/docs/api/java/util/UUID. html) может предоставить эту последнюю. – Sandro

13

Ну, source code показывает UUID.randomUUID использует SecureRandom.

public static UUID [More ...] randomUUID() { 
    SecureRandom ng = numberGenerator; 
    if (ng == null) { 
     numberGenerator = ng = new SecureRandom(); 
    } 
    byte[] randomBytes = new byte[16]; 
    ng.nextBytes(randomBytes); 
    randomBytes[6] &= 0x0f; /* clear version  */ 
    randomBytes[6] |= 0x40; /* set to version 4  */ 
    randomBytes[8] &= 0x3f; /* clear variant  */ 
    randomBytes[8] |= 0x80; /* set to IETF variant */ 
    return new UUID(randomBytes); 
} 

Как вы можете видеть, вы можете использовать либо, но в безопасном UUID у вас есть 6 неслучайные биты, которые можно считать недостатком, если вы придирчивы.

+0

Да, если я хочу сгенерировать уникальные идентификаторы, я смогу сделать это, используя SecureRandom самостоятельно? Было бы так же хорошо, как получить UUID типа 4. Но может быть, я могу генерировать уникальные идентификаторы с большим количеством бит, заполненных случайным образом, чем 122. Это правильно? – User3518958

+1

Да, вы можете это сделать. Но, если вы хотите использовать его как UUID, я бы предложил использовать randomUUID. Эти 6 бит находятся в спецификации UUID, и приятно сохранять верность спецификациям: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 – uoyilmaz

+0

Ох, или, я думаю, я должен изучить, что именно частный конструктор UUID (randomBytes); делает. – User3518958

2

Случайные числа имеют случайную вероятность повторения. Чем ниже случайность (если не существует некоторой координации), тем выше вероятность того, что будет производить тот же номер дважды.

https://en.wikipedia.org/wiki/Birthday_problem
Поскольку вы производите более случайные числа, вероятность повторения одного и того же числа увеличивается, поскольку каждый идентификатор должен отличаться от любого другого идентификатора.

SecureRandom позволяет вам выбирать, сколько бит случайности вы хотите. Сделайте его слишком маленьким, и есть хорошие шансы, что они будут повторяться. Вы можете получить дубликат случайного 32-битного id за долю секунды.

UUID устанавливает стандарт на 128 бит (или, как указывает uoyilmaz, 122 бит являются случайными) Этого достаточно для большинства случаев использования. Однако, если вы хотите случайную String, у меня возникнет соблазн использовать больше бит и/или более высокую базу, чем 16. Java, например, поддерживает базы 36 и 64, что означает, что вы можете иметь более короткие идентификаторы или больше случайности для одинакового идентификатора длины.

Примечание: формат UUID имеет несколько - в его дампе, хотя я не вижу их значения, они просто делают строку длиннее.

Смежные вопросы