Python. Зачем использовать что-то кроме uuid4() для уникальных строк?

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

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

>>> import uuid
>>> uuid.uuid4()
UUID('07033084-5cfd-4812-90a4-e4d24ffb6e3d')

И я закончил с этим. Я не очень доверял, пока не прочитал про uuid, поэтому сделал так:

>>> import uuid
>>> s = set()
>>> for i in range(5000000):  # That's 5 million!
>>>     s.add(str(uuid.uuid4()))
...
...
>>> len(s)
5000000

Ни одного ретранслятора (я бы не ожидал, что он появится сейчас, учитывая шансы примерно 1,108e+50, но приятно видеть его в действии). Вы можете даже вдвое уменьшить шансы, просто составив свою строку, объединив 2 uuid4().

Итак, с учетом сказанного, почему люди тратят время на random() и другие вещи для уникальных строк и т. д.? Есть ли важная проблема безопасности или другая проблема, связанная с uuid?


person orokusaki    schedule 12.03.2010    source источник
comment
Кстати, удвоение длины uuid возведет в квадрат количество возможных значений, а не просто удвоит.   -  person Matt Good    schedule 12.03.2010


Ответы (6)


Использование хэша для уникальной идентификации ресурса позволяет создать «уникальную» ссылку на объект. Например, Git использует хеширование SHA для создания уникального хэша, представляющего точный набор изменений одного коммита. Поскольку хеширование является детерминированным, вы каждый раз будете получать один и тот же хэш для одного и того же файла.

Два человека по всему миру могут независимо внести одно и то же изменение в один и тот же репозиторий, и Git будет знать, что они внесли одно и то же изменение. UUID v1, v2 и v4 не могут поддерживать это, поскольку они не имеют отношения к файлу или содержимому файла.

person Arion    schedule 10.09.2012
comment
Возражение! UUID на самом деле могут быть детерминированными! UUIDv3 основан на хэше MD5, а UUIDv5 основан на хэше SHA-1. - person starlocke; 28.10.2013
comment
Следует выбрать UUIDv3 или UUIDv5 для детерминированных вещей (загруженные файлы, наборы изменений git и т. д.), а UUIDv1, UUIDv2 или UUIDv4 — для временных, недетерминированных (сеансы, временные файлы и т. д.). - person starlocke; 28.10.2013
comment
Кстати, git включает информацию об авторе и дату фиксации в наборы изменений, поэтому одни и те же изменения, внесенные разными людьми, не будут давать одинаковый хэш. Однако объектные файлы, сохраненные в папке .git, являются допустимым вариантом использования. - person Amir Ali Akbari; 29.07.2015

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

person Ben Voigt    schedule 12.03.2010
comment
@Ben, не могли бы вы просто сохранить имя изображения в качестве другого поля в строке и использовать логику программирования, чтобы перезаписать существующее изображение, или сказать «упс», когда они снова загружают одно и то же изображение. - person orokusaki; 12.03.2010
comment
Его точка зрения по-прежнему актуальна: иногда вам нужны коллизии, а GUID их не предлагает. Сказав это, любой, кто использует SHA-1 для поиска уникальной строки, вероятно, делает что-то неправильно, так как его вывод почти наверняка менее уникален, чем его ввод. - person ladenedge; 12.03.2010
comment
@ladenedge Я думаю, что SHA1 является частью уравнения, просто чтобы получить более нормализованное значение (в случае наличия пробелов и т. д.). - person orokusaki; 12.03.2010
comment
@orokusaki: имя изображения генерируется в соответствии с первой строкой вопроса. Итак, как это поможет вам идентифицировать дубликаты, если только это не хеш на содержании? - person Ben Voigt; 12.03.2010
comment
Вот моя строка БД [image_name, image_filename, some_other_field, so_on_and_so_on]. Если я получаю запрос на добавление нового изображения с существующим image_name, я просто нахожу соответствующий image_filename и заменяю его. Кто будет использовать фактическое имя файла изображения для своей системы записи? Я разрабатываю архитектуру с несколькими арендаторами, поэтому 5000 клиентов могли загрузить logo.jpg. Я бы не стал полагаться только на наличие отдельных папок для каждого клиента, потому что тогда, если я изменю свою файловую систему на какую-нибудь классную новую систему, подобную S3, я не хочу создавать новые сегменты для каждого клиента. Это кошмар. - person orokusaki; 14.03.2010

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

person Jason Baker    schedule 12.03.2010

uuid длинные и бессмысленные (например, если вы заказываете по uuid, вы получаете бессмысленный результат).

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

person hasen    schedule 12.03.2010
comment
Да, но для этого и нужен shortuuid. Вся энтропия, никакой длины. - person Stavros Korokithakis; 08.05.2013

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

person David K. Hess    schedule 24.10.2014

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

person jsh    schedule 01.02.2016