Вероятность столкновения при использовании старших битов UUID в Java

Если я использую Long uuid = UUID.randomUUID().getMostSignificantBits(), насколько вероятно столкновение. Он отрезает наименее значимые биты, так что есть вероятность столкновения, верно?

Решение

Согласно документации, статический метод UUID.randomUUID() генерирует UUID типа 4.

Это означает, что шесть бит используются для некоторой информации о типе, а оставшиеся 122 бита назначаются случайным образом.

Шесть неслучайных битов распределяются так: четыре в старшей половине UUID и два в младшей. Таким образом, наиболее значимая половина вашего UUID содержит 60 битов случайности, что означает, что в среднем вам нужно сгенерировать 2^30 UUID, чтобы получить коллизию (по сравнению с 2^61 для полного UUID).

Поэтому я бы сказал, что вы находитесь в полной безопасности. Заметьте, однако, что это абсолютно не верно для других типов UUID, как упоминает Карл Селеборг.

Кстати, вам будет немного лучше, если вы будете использовать наименьшую половину UUID (или просто генерировать случайную длину с помощью SecureRandom).

Комментарии (3)

Я думаю, это лучший пример для использования randomUUID :

http://www.javapractices.com/topic/TopicAction.do?Id=56

Комментарии (0)

Лучше просто сгенерировать случайное длинное значение, тогда все биты будут случайными. В Java 6 новая функция Random() использует System.nanoTime() плюс счетчик в качестве затравки.

Существуют различные уровни уникальности.

Если вам нужна уникальность для многих машин, вы можете иметь центральную таблицу базы данных для распределения уникальных идентификаторов или даже партии уникальных идентификаторов.

Если вам нужна уникальность только в одном приложении, вы можете просто иметь счетчик (или счетчик, который начинается с текущего времени (CurrentTimeMillis()*1000 или nanoTime(), в зависимости от ваших требований).

Комментарии (0)

Использовать время YYYYDDDD (год + день года) в качестве префикса. Это уменьшает фрагментацию базы данных в таблицах и индексах. Байт этот метод возвращает [40]. Я использовал его в гибридной среде, где активно Сида каталог (типа varbinary(85)) является ключевым для пользователей LDAP и приложение автоматически сгенерированный идентификатор используется для non-пользователей в LDAP. Также большое количество транзакций в день в транзакционных таблиц (банковской сфере) не может использовать типы стандартных типа int для ключей

private static final DecimalFormat timeFormat4 = new DecimalFormat("0000;0000");

public static byte[] getSidWithCalendar() {
    Calendar cal = Calendar.getInstance();
    String val = String.valueOf(cal.get(Calendar.YEAR));
    val += timeFormat4.format(cal.get(Calendar.DAY_OF_YEAR));
    val += UUID.randomUUID().toString().replaceAll("-", "");
    return val.getBytes();
}
Комментарии (1)