Когда я должен использовать uuid.uuid1 () против uuid.uuid4 () в python?



Я понимаю разницу между двумя из docs.



uuid1():

Сгенерируйте UUID из идентификатора хоста, порядкового номера и текущего времени



uuid4():

Сгенерируйте случайный UUID.



так uuid1 использует информацию о машине / последовательности / времени для создания UUID. Каковы плюсы и минусы использования каждого?



Я знаю uuid1() может иметь проблемы конфиденциальности, так как он основан на Машинной информации. Интересно, если есть более тонкие при выборе одного или другого. Я просто использую uuid4() прямо сейчас, так как это совершенно случайный UUID. Но мне интересно, если я должен использовать uuid1 чтобы уменьшить риск столкновения.



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

594   6  

6 ответов:

uuid1() гарантированно не создает никаких коллизий (при условии, что вы не создаете слишком много из них одновременно). Я бы не использовал его, если это важно, что нет никакой связи между uuid и компьютер, поскольку mac-адрес используется, чтобы сделать его уникальным на разных компьютерах.

вы можете создать дубликаты, создав более 214 uuid1 менее чем за 100 нс, но это не проблема для большинства случаев использования.

uuid4() генерирует, как вы сказали, случайный UUID. Вероятность столкновения действительно, действительно, действительно небольшой. Достаточно маленький, чтобы вы не беспокоились об этом. Проблема в том, что плохой генератор случайных чисел делает его более вероятным для столкновений.

это отличный ответ от Боба Амана подводит итог красиво. (Рекомендую прочитать весь ответ.)

честно говоря, в одном пространстве приложений без злонамеренных актеров, вымирание всей жизни на земле возникают задолго до вас столкновение, даже на версии 4 UUID, даже если вы создаете несколько Идентификаторы UUID в секунду.

один пример, когда вы можете рассмотреть uuid1(), а не uuid4() и когда UUIDs производятся на отдельных машинах, например, когда несколько онлайн-транзакций обрабатываются на нескольких машинах для целей масштабирования.

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

еще один интерес uuid1(), в этом случае машина, где каждый GUID был первоначально создан, неявно записывается (в "узловой" части UUID). Это и информация о времени, может помочь, если только с отладкой.

моя команда просто столкнулась с проблемами, используя UUID1 для сценария обновления базы данных, где мы сгенерировали ~120k UUIDs в течение нескольких минут. Столкновение UUID привело к нарушению ограничения первичного ключа.

мы обновили 100s серверов, но на наших инстансах Amazon EC2 мы столкнулись с этой проблемой несколько раз. Я подозреваю, что плохое разрешение часов и переход на UUID4 решили его для нас.

одна вещь, чтобы отметить при использовании uuid1, Если вы используете вызов по умолчанию (не давая clock_seq параметр) у вас есть шанс столкнуться с столкновениями: у вас есть только 14 бит случайности (генерация 18 записей в пределах 100 нс дает вам примерно 1% шанс столкновения см. день рождения парадокс/атака). Проблема никогда не возникнет в большинстве случаев использования, но на виртуальной машине с плохим разрешением часов она укусит вас.

возможно, что-то, что не было упомянуто, - это локальность.

MAC-адрес или упорядочение по времени (UUID1) может позволить повысить производительность базы данных, так как это меньше работы для сортировки чисел ближе друг к другу, чем те, распределенные случайным образом (UUID4) (см. здесь).

вторая связанная проблема заключается в том, что использование UUID1 может быть полезно при отладке, даже если исходные данные потеряны или явно не сохранены (это, очевидно, противоречит проблеме конфиденциальности упомянутый ОП).

В дополнение к принятой ответ, есть третий вариант, который может быть полезен в некоторых случаях:

v1 со случайным MAC ("v1mc")

вы можете сделать гибрид между v1 и v4, намеренно генерируя V1 UUIDs со случайным широковещательным MAC-адресом (это разрешено спецификацией v1). Полученный UUID v1 зависит от времени (например, обычный v1), но ему не хватает всей информации о хосте (например, v4). Это также намного ближе к v4 в его столкновении сопротивления: v1mc = 60 бит время + 61 случайный бит = 121 уникальный бит; v4 = 122 случайных бит.

первое место, где я столкнулся с этим, было Postgres'uuid_generate_v1mc (). С тех пор я использовал следующий эквивалент python:

from os import urandom
from uuid import uuid1
_int_from_bytes = int.from_bytes  # py3 only

def uuid1mc():
    # NOTE: The constant here is required by the UUIDv1 spec...
    return uuid1(_int_from_bytes(urandom(6), "big") | 0x010000000000)

(Примечание: у меня есть более длинная + более быстрая версия, которая создает объект UUID напрямую; может публиковать, если кто-то хочет)


В случае больших объемов вызовов / во-вторых, это может привести к случайности выхлопной системы. Ты может использовать stdlib random модуль вместо (это, вероятно, также будет быстрее). Но имейте в виду: требуется всего несколько сотен UUID, прежде чем злоумышленник сможет определить состояние RNG и, таким образом, частично предсказать будущие UUID.

import random
from uuid import uuid1

def uuid1mc_insecure():
    return uuid1(random.getrandbits(48) | 0x010000000000)

Comments

    Ничего не найдено.