Создать GUID в Java

378

Каковы некоторые из лучших способов создания GUID в Java?

Крис Датроу
источник
3
Вопрос на stackoverflow.com/questions/325443/generate-uuid-in-java больше о коллизиях GUID, чем о том, каков эквивалент GUID в техническом стеке Java, а именно (я думаю) больше фокус этого вопроса.
Джон Адамс

Ответы:

348

Посмотрите на класс UUID, связанный с Java 5 и более поздними версиями.

Например:

  • Если вам нужен случайный UUID, вы можете использовать метод randomUUID .
  • Если вы хотите, чтобы UUID инициализировался определенным значением, вы можете использовать конструктор UUID или метод fromString .
Марк Байерс
источник
7
Если вы включите пример, как Kaleb Brasee, ваш хороший ответ будет еще лучше.
Zero3
Работает в AndroidStudio 2.3 и API по крайней мере 21 уровня и выше. Может быть, еще дальше.
Раддевус
6
TL; DR ... "UUID uuid = UUID.randomUUID ();"
Авирам Файербергер
420

java.util.UUID.randomUUID();

Калеб Бразе
источник
2
может ли это повторить? потому что гуид никогда не повторится
ангел
4
@angel Да, для UUID.randomUUIDметода теоретически возможно возвратить дубликат, но это вовсе не является реальной проблемой . Реализация Oracle / OpenJDK использует криптографически сильный генератор случайных чисел. Учитывая это и учитывая астрономический диапазон, заданный таким количеством битов в UUID, вы можете сгенерировать много миллионов таких значений в своем приложении и все еще спать спокойно. Использование одного из других вариантов дополнительно уменьшает вероятность коллизий даже ближе к нулю из-за использования в качестве ограничений «пространства и времени», [1] MAC-адреса или имени и [2] текущей даты-времени.
Василий Бурк
@RenniePet Да, если вы параноик, и вы получили доступ к списку уже использованных идентификаторов при создании нового, вы просто генерируете новые в, whileпока не получите тот, которого нет в вашем списке: p
Нергудс
2
Генератор крипто-случайных чисел Oracle, как правило, представляет собой PRNG со случайным начальным числом. Случайное начальное число обычно получается с использованием источника «энтропии», предоставляемого ОС. Если вы можете ухудшить или скомпрометировать этот источник, то вероятность того, что генератор криптографических случайных чисел выдаст то же число, увеличится. Стоит также отметить, что на некоторых (например, виртуализированных) платформах ОС может выйти из-за энтропии. Есть обходные пути, чтобы обойти это, но они влекут за собой ухудшение качества энтропии.
Стивен С
Это не просто академическая проблема. Я видел ( непроверенный !! ) утверждает , что кто - то сделали столкнется с проблемами со случайным на основе UUID , не является уникальным.
Стивен С.
32

Это зависит от того, какой тип UUID вы хотите.

  • Стандартный UUIDкласс Java генерирует случайные UUID версии 4 . ( ОБНОВЛЕНИЕ - UUID версии 3 (имя) также могут быть сгенерированы.) Он также может обрабатывать другие варианты, хотя он не может генерировать их. (В этом случае «дескриптор» означает создание UUIDэкземпляров из long,byte[] или Stringпредставления, и предоставляют некоторые соответствующие аксессор.)

  • Реализация Java UUID Generator (JUG) подразумевает поддержку «всех 3« официальных »типов UUID, как определено в RFC-4122 » ... хотя RFC фактически определяет 4 типа и упоминает 5-й тип.

Для получения дополнительной информации о типах и вариантах UUID в Википедии есть хорошее резюме , а подробности - в RFC 4122 и других спецификациях.

Стивен С
источник
1
Не совсем верно, он также может генерировать UUID на основе имени (версия 3) сUUID.nameUUIDFromBytes(byte[] name)
DennisK
Я стою исправлено. Я опирался на описание javadoc, которое гласит: «Статическая фабрика для получения UUID типа 3 (на основе имени) на основе указанного байтового массива».
Стивен С.
Я не думаю, что сообщение является точным. Документы UUID Java заявляют, что конструктор генерирует вариант типа 2, а не случайный. Для типа 3 используйте public static UUID nameUUIDFromBytes(byte[] name). для использования типа 4 public static UUID randomUUID(). Тип 1 недоступен в классе JDK.
slartibartfast
Нет. Я думаю, я понял это правильно. Javadocs заявляет: «хотя конструкторы допускают создание любого варианта UUID (описанного ниже)». и 4 варианта перечислены ниже, в том числе тип 1. Действительно, прочитайте Javadoc дляclockSequence()
Стивен C
27

Просто чтобы расширить ответ Марка Байерса на примере:

import java.util.UUID;

public class RandomStringUUID {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        System.out.println("UUID=" + uuid.toString() );
    }
}
Антон Белев
источник
7

Другие ответы правильны, особенно это одна от Stephen C .

Достижение за пределами Java

Генерация значения UUID в Java ограничена версией 4 (случайной) из соображений безопасности.

Если вам нужны другие версии UUID, один из способов заключается в том, чтобы ваше Java-приложение выходило за пределы JVM для генерации UUID путем вызова:

  • Утилита командной строки
    Входит практически в каждую операционную систему.
    Например, uuidgenв Mac OS X, BSD и Linux.
  • Сервер базы данных
    Используйте JDBC для получения UUID, сгенерированного на сервере базы данных.
    Например, uuid-osspрасширение часто в комплекте с Postgres . Это расширение может генерировать значения версий 1, 3 и 4 и дополнительно пару вариантов:
    • uuid_generate_v1mc() - генерирует UUID версии 1, но использует реальный многоадресный MAC-адрес вместо реального MAC-адреса компьютера.
    • uuid_generate_v5(namespace uuid, name text) - генерирует UUID версии 5, который работает как UUID версии 3, за исключением того, что SHA-1 используется в качестве метода хеширования.
  • Веб-служба
    Например, UUID Generator создает версии 1 и 3, а также значения nil и GUID .
Базилик Бурк
источник
3
У меня есть некоторые проблемы с вашим ответом: во-первых, уже было показано, что вы ошибаетесь, что вы можете получить V4 только из стандартной библиотеки Java (V3 также возможен). Во-вторых, вы делаете так, чтобы в Java не было никаких опций, кроме стандартной библиотеки, а также волнообразного «из соображений безопасности». И, наконец, вообще неэффективно (в программировании и / или с точки зрения производительности) начинать в зависимости от внешних источников, когда есть множество способов сделать это в Java (если, конечно, вам это не нужно, например, как часть создания запись на сервере SQL).
DennisK