Как создать GUID / UUID в Python

Как создать в Python GUID, независимый от платформы? Я слышал, что есть метод, использующий ActivePython в Windows, но это Windows только потому, что он использует COM. Есть ли метод, использующий простой Python?


person Jonathon Watney    schedule 10.02.2009    source источник
comment
docs.activestate.com/activepython/2.6/python/library/uuid. html   -  person Sridhar Ratnakumar    schedule 20.01.2010
comment
Во имя любви ко всему священному, это UUID - универсальный уникальный идентификатор en.wikipedia.org/wiki/ Universally_unique_identifier - к сожалению, MS предпочла GUID.   -  person david.barkhuizen    schedule 17.03.2013
comment
Вот вам один лайнер: python -c 'import uuid; print(uuid.uuid4())'   -  person Ctrl-C    schedule 24.04.2017
comment
Я думаю, что GUID имеет больше смысла, чем UUID, поскольку ‹i› global ‹/i› означает глобальный в некотором пространстве имен, в то время как ‹i› универсальный ‹/i›, похоже, претендует на истинную универсальную уникальность. В любом случае мы все знаем, о чем здесь говорим.   -  person duhaime    schedule 28.10.2020


Ответы (8)


модуль uuid предоставляет неизменяемые объекты UUID (класс UUID) и функции uuid1 ( ), uuid3 (), uuid4 (), uuid5 () для создания UUID версий 1, 3, 4 и 5, как указано в RFC 4122.

Если вам нужен только уникальный идентификатор, вам, вероятно, следует вызвать uuid1 () или uuid4 (). Обратите внимание, что uuid1 () может нарушить конфиденциальность, поскольку он создает UUID, содержащий сетевой адрес компьютера. uuid4 () создает случайный UUID.

Документы:

Примеры (для Python 2 и 3):

>>> import uuid

>>> # make a random UUID
>>> uuid.uuid4()
UUID('bd65600d-8669-4903-8a14-af88203add38')

>>> # Convert a UUID to a string of hex digits in standard form
>>> str(uuid.uuid4())
'f50ec0b7-f960-400d-91f0-c42a6d44e3d0'

>>> # Convert a UUID to a 32-character hexadecimal string
>>> uuid.uuid4().hex
'9fe2c4e93f654fdbb24c02b15259716c'
person stuartd    schedule 10.02.2009
comment
Также обратите внимание на модуль shortuuid, который я написал, поскольку он позволяет создавать более короткие и удобные для чтения UUID: github .com / stochastic-technologies / shortuuid - person Stavros Korokithakis; 31.12.2012
comment
@StavrosKorokithakis: вы случайно не написали модуль shortuuid для Python 3.x? - person Jay Patel; 22.08.2016
comment
@JayPatel Shortuuid не работает для Python 3? Если нет, сообщите об ошибке. - person Stavros Korokithakis; 22.08.2016
comment
В чем разница между uuid4().hex и str(uuid4())? - person Kevin; 30.01.2018
comment
Что ж, как вы можете видеть выше, str(uuid4()) возвращает строковое представление UUID с включенными дефисами, а uuid4().hex возвращает UUID в виде 32-символьной шестнадцатеричной строки - person stuartd; 30.01.2018
comment
спасибо инфа по uuid1 и uuid4 очень кстати! ваше здоровье :) - person ThomasLYIT; 04.04.2021

Если вы используете Python 2.5 или более поздней версии, Модуль uuid уже включен в стандартный дистрибутив Python.

Ex:

>>> import uuid
>>> uuid.uuid4()
UUID('5361a11b-615c-42bf-9bdb-e2c3790ada14')
person Jay    schedule 10.02.2009

Скопировано с: https://docs.python.org/2/library/uuid.html (поскольку размещенные ссылки не были активными и продолжают обновляться)

>>> import uuid

>>> # make a UUID based on the host ID and current time
>>> uuid.uuid1()
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

>>> # make a UUID using an MD5 hash of a namespace UUID and a name
>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')

>>> # make a random UUID
>>> uuid.uuid4()
UUID('16fd2706-8baf-433b-82eb-8c7fada847da')

>>> # make a UUID using a SHA-1 hash of a namespace UUID and a name
>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

>>> # make a UUID from a string of hex digits (braces and hyphens ignored)
>>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')

>>> # convert a UUID to a string of hex digits in standard form
>>> str(x)
'00010203-0405-0607-0809-0a0b0c0d0e0f'

>>> # get the raw 16 bytes of the UUID
>>> x.bytes
'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'

>>> # make a UUID from a 16-byte string
>>> uuid.UUID(bytes=x.bytes)
UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
person Balaji Boggaram Ramanarayan    schedule 04.12.2014

Я использую идентификаторы GUID в качестве случайных ключей для операций типа базы данных.

Шестнадцатеричная форма с дефисами и лишними символами кажется мне излишне длинной. Но мне также нравится, что строки, представляющие шестнадцатеричные числа, очень безопасны, поскольку они не содержат символов, которые могут вызвать проблемы в некоторых ситуациях, таких как '+', '=' и т. Д.

Вместо шестнадцатеричного я использую строку base64, безопасную для URL. Следующее не соответствует ни одной спецификации UUID / GUID (кроме необходимой степени случайности).

import base64
import uuid

# get a UUID - URL safe, Base64
def get_a_uuid():
    r_uuid = base64.urlsafe_b64encode(uuid.uuid4().bytes)
    return r_uuid.replace('=', '')
person Chris Dutrow    schedule 11.06.2012
comment
Если вы не собираетесь использовать его в каких-либо контекстах UUID, вы также можете просто использовать random.getrandbits(128).to_bytes(16, 'little') или (для криптографической случайности) os.urandom(16) и получить полные 128 бит случайности (UUIDv4 использует 6-7 бит в информации о версии). Или используйте только 15 байтов (потеря 1-2 бита случайного значения по сравнению с UUIDv4) и избегайте необходимости обрезать знаки =, а также уменьшите кодированный размер до 20 байтов (с 24, обрезанных до 22), как любое кратное 3 байтам кодируется в #bytes / 3 * 4 символов base64 без заполнения. - person ShadowRanger; 24.01.2019
comment
@ShadowRanger Да, в этом и идея. 128 случайных битов, как можно короче и безопасны для URL-адресов. В идеале он должен использовать только прописные и строчные буквы, а затем цифры. Итак, я предполагаю, что это строка с основанием 62. - person Chris Dutrow; 15.02.2019
comment
Когда я использую вашу функцию, я получаю ошибку типа из оператора return, ожидающего байтовый объект. Это можно исправить с помощью return str(r_uuid).replace('=',''). - person Mark Kortink; 18.02.2020

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

 import uuid
 uuid.uuid4()

Если вам нужно передать UUID в качестве параметра для URL-адреса, вы можете сделать так, как показано ниже:

import uuid
str(uuid.uuid4())

Если вам нужно шестнадцатеричное значение для UUID, вы можете сделать следующее:

import uuid    
uuid.uuid4().hex
person Mobasshir Bhuiya    schedule 25.06.2019

Эта функция полностью настраивается и генерирует уникальный uid на основе указанного формата.

например: - [8, 4, 4, 4, 12], это упомянутый формат, и он будет генерировать следующий uuid

LxoYNyXe-7hbQ-caJt-DSdU-PDAht56cMEWi

 import random as r

 def generate_uuid():
        random_string = ''
        random_str_seq = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        uuid_format = [8, 4, 4, 4, 12]
        for n in uuid_format:
            for i in range(0,n):
                random_string += str(random_str_seq[r.randint(0, len(random_str_seq) - 1)])
            if n != 12:
                random_string += '-'
        return random_string
person Manoj Selvin    schedule 24.02.2018
comment
UUID являются стандартными и не меняются по длине. Создание случайной строки настраиваемым способом может быть полезно в некоторых ситуациях, но не в этом контексте. Вы можете проверить определение en.wikipedia.org/wiki/Universally_unique_identifier. - person miguelr; 29.01.2019
comment
Лучше избегайте этого, иначе вы можете столкнуться с проблемами совместимости (это не стандартные идентификаторы GUID) - person Sylvain Gantois; 10.09.2019
comment
Кроме того, даже отдаленно не гарантируется уникальность. Он может быть случайным, но не уникальным. - person regretoverflow; 14.12.2020
comment
@regretoverflow Никакие идентификаторы GUID никогда не бывают уникальными, просто настолько массивными, что коллизия крайне маловероятна. - person Austin Heller; 27.06.2021

Ответ 2019 (для Windows):

Если вам нужен постоянный UUID, который однозначно идентифицирует машину в Windows, вы можете использовать этот трюк: (Скопировано из моего ответа на https://stackoverflow.com/a/58416992/8874388).

from typing import Optional
import re
import subprocess
import uuid

def get_windows_uuid() -> Optional[uuid.UUID]:
    try:
        # Ask Windows for the device's permanent UUID. Throws if command missing/fails.
        txt = subprocess.check_output("wmic csproduct get uuid").decode()

        # Attempt to extract the UUID from the command's result.
        match = re.search(r"\bUUID\b[\s\r\n]+([^\s\r\n]+)", txt)
        if match is not None:
            txt = match.group(1)
            if txt is not None:
                # Remove the surrounding whitespace (newlines, space, etc)
                # and useless dashes etc, by only keeping hex (0-9 A-F) chars.
                txt = re.sub(r"[^0-9A-Fa-f]+", "", txt)

                # Ensure we have exactly 32 characters (16 bytes).
                if len(txt) == 32:
                    return uuid.UUID(txt)
    except:
        pass # Silence subprocess exception.

    return None

print(get_windows_uuid())

Использует Windows API для получения постоянного UUID компьютера, затем обрабатывает строку, чтобы убедиться, что это действительный UUID, и, наконец, возвращает объект Python (https://docs.python.org/3/library/uuid.html), который дает вам удобные способы использования данных (таких как 128-битное целое число, шестнадцатеричная строка, так далее).

Удачи!

PS: вызов подпроцесса, вероятно, можно было бы заменить ctypes, напрямую вызывающим ядро ​​/ DLL Windows. Но для моих целей эта функция - все, что мне нужно. Он выполняет строгую проверку и дает правильные результаты.

person Mitch McMabers    schedule 16.10.2019

Проверьте эту запись, мне очень помогло. Короче, оптимальным вариантом для меня было:

import random 
import string 

# defining function for random 
# string id with parameter 
def ran_gen(size, chars=string.ascii_uppercase + string.digits): 
    return ''.join(random.choice(chars) for x in range(size)) 

# function call for random string 
# generation with size 8 and string  
print (ran_gen(8, "AEIOSUMA23")) 

Потому что мне нужно было всего 4-6 случайных символов вместо громоздкого GUID.

person QtRoS    schedule 05.12.2019
comment
Это кажется совершенно не связанным с вопросом о UUID. - person sox with Monica; 27.04.2020