Я написал UUID-генератор / синтаксический анализатор для Ruby, поэтому я считаю себя достаточно хорошо осведомленным в этом вопросе. Существует четыре основных версии UUID:
UUID версии 4 - это всего лишь 16 байтов случайности, извлекаемые из криптографически безопасного генератора случайных чисел, с небольшим изменением бит для идентификации версии и варианта UUID. Это очень маловероятно, чтобы столкнуться, но это может произойти, если используется PRNG или если у вас просто действительно, действительно, действительно, действительно, действительно, очень неудача.
UUID версии 5 и 3 используют хеш-функции SHA1 и MD5 соответственно, чтобы объединить пространство имен с частью уже уникальных данных для генерации UUID. Это, например, позволит вам создать UUID из URL. Столкновения здесь возможны, только если основная хеш-функция также имеет столкновение.
UUID версии 1 являются наиболее распространенными. Они используют MAC-адрес сетевой карты (который, если не был подделан, должен быть уникальным), а также временную метку и обычное переключение битов для генерации UUID. В случае машины, у которой нет MAC-адреса, 6 байтов узла генерируются с помощью криптографически безопасного генератора случайных чисел. Если два UUID генерируются последовательно достаточно быстро, чтобы временная метка соответствовала предыдущему UUID, временная метка увеличивается на 1. Коллизии не должны возникать, если не произойдет одно из следующего: MAC-адрес подделан; Одна машина, на которой работают два разных приложения, генерирующих UUID, генерирует UUID в один и тот же момент; Две машины без сетевой карты или без доступа уровня пользователя к MAC-адресу получают одинаковую последовательность случайных узлов и генерируют идентификаторы UUID в один и тот же момент; У нас заканчиваются байты для представления метки времени и перехода на ноль.
Реально, ни одно из этих событий не происходит случайно в пределах пространства идентификаторов одного приложения. Если вы не принимаете идентификаторы, скажем, в масштабе Интернета или в ненадежной среде, где злоумышленники могут сделать что-то плохое в случае коллизии идентификаторов, вам просто не о чем беспокоиться. Важно понимать, что если вы генерируете тот же UUID версии 4, что и я, в большинстве случаев это не имеет значения. Я сгенерировал идентификатор в совершенно другом пространстве идентификаторов, чем у вас. Мое приложение никогда не узнает о столкновении, поэтому столкновение не имеет значения. Честно говоря, в одном пространстве приложений без злонамеренных акторов вымирание всей жизни на Земле произойдет задолго до того, как вы столкнетесь, даже с UUID версии 4, даже если вы генерируете довольно много UUID в секунду.
Кроме того, 2 ^ 64 * 16 - это 256 эксабайт. Например, вам нужно будет хранить идентификаторы на 256 экзабайт, прежде чем у вас будет 50% вероятность коллизии идентификаторов в одном пространстве приложения.