So erstellen Sie eine GUID / UUID in Python


685

Wie erstelle ich in Python eine GUID, die plattformunabhängig ist? Ich habe gehört, dass es eine Methode gibt, die ActivePython unter Windows verwendet, aber es ist nur Windows, weil es COM verwendet. Gibt es eine Methode mit einfachem Python?



34
Für die Liebe zu allem, was heilig ist, ist es eine UUID - Universal Unique ID en.wikipedia.org/wiki/Universally_unique_identifier - es ist nur so, dass MS leider die GUID bevorzugt hat.
David.Barkhuizen

5
Hier ist ein Liner für Sie:python -c 'import uuid; print(uuid.uuid4())'
Strg-C

Antworten:


776

Das UUID-Modul in Python 2.5 und höher bietet eine RFC-kompatible UUID-Generierung. Weitere Informationen finden Sie in den Moduldokumenten und im RFC. [ Quelle ]

Docs:

Beispiel (Arbeiten an 2 und 3):

>>> import uuid
>>> uuid.uuid4()
UUID('bd65600d-8669-4903-8a14-af88203add38')
>>> str(uuid.uuid4())
'f50ec0b7-f960-400d-91f0-c42a6d44e3d0'
>>> uuid.uuid4().hex
'9fe2c4e93f654fdbb24c02b15259716c'

20
Schauen Sie sich auch das shortuuidModul an, das ich geschrieben habe, da es Ihnen ermöglicht, kürzere, lesbare UUIDs zu generieren: github.com/stochastic-technologies/shortuuid
Stavros Korokithakis

2
@StavrosKorokithakis: Haben Sie zufällig ein Shortuuid-Modul für Python 3.x geschrieben?
Jay Patel

2
@ JayPatel Funktioniert Shortuuid nicht für Python 3? Wenn nicht, melden Sie bitte einen Fehler.
Stavros Korokithakis

1
Was ist der Unterschied zwischen uuid4().hexund str(uuid4())?
Kevin

6
Nun, wie Sie oben sehen können, str(uuid4())gibt eine String - Darstellung des UUID mit der Striche enthalten, während uuid4().hexkehrt „Die UUID als 32-Zeichen Hexadezimalstring“
stuartd

324

Wenn Sie Python 2.5 oder höher verwenden, ist das uuid-Modul bereits in der Python-Standarddistribution enthalten.

Ex:

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

116

Kopiert von: https://docs.python.org/2/library/uuid.html (Da die veröffentlichten Links nicht aktiv waren und ständig aktualisiert werden)

>>> 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')

28

Ich verwende GUIDs als zufällige Schlüssel für Operationen vom Datenbanktyp.

Die hexadezimale Form mit den Strichen und zusätzlichen Zeichen erscheint mir unnötig lang. Aber ich mag auch, dass Zeichenfolgen, die Hexadezimalzahlen darstellen, sehr sicher sind, da sie keine Zeichen enthalten, die in bestimmten Situationen Probleme verursachen können, wie z. B. '+', '=' usw.

Anstelle von hexadezimal verwende ich eine url-sichere base64-Zeichenfolge. Das Folgende entspricht jedoch keiner UUID / GUID-Spezifikation (außer der erforderlichen Zufälligkeit).

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('=', '')

2
Wenn Sie sich nicht die Mühe machen, es in UUID-Kontexten zu verwenden, können Sie auch einfach random.getrandbits(128).to_bytes(16, 'little')oder (für Krypto-Zufälligkeit) verwenden os.urandom(16)und volle 128 Bit Zufall erhalten (UUIDv4 verwendet 6-7 Bit für Versionsinformationen). Oder verwenden Sie nur 15 Bytes (Verlust von 1-2 zufälligen Bits im Vergleich zu UUIDv4) und vermeiden Sie die Notwendigkeit, =Zeichen abzuschneiden , während Sie gleichzeitig die codierte Größe auf 20 Bytes (von 24 auf 22) reduzieren, da ein Vielfaches von 3 Bytes codiert auf #bytes / 3 * 4base64 Zeichen ohne Auffüllen erforderlich.
ShadowRanger

@ ShadowRanger Ja, das ist im Grunde die Idee. 128 zufällige Bits, so kurz wie möglich und gleichzeitig URL-sicher. Im Idealfall werden nur Groß- und Kleinbuchstaben und dann Zahlen verwendet. Also denke ich eine Base-62-Saite.
Chris Dutrow

Wenn ich Ihre Funktion benutze, erhalte ich einen Typfehler von der returnAnweisung, die ein byteähnliches Objekt erwartet. Es kann mit behoben werden return str(r_uuid).replace('=','').
Mark Kortink

8

Wenn Sie die UUID für einen Primärschlüssel für Ihr Modell oder ein eindeutiges Feld übergeben müssen, gibt der folgende Code das UUID-Objekt zurück -

 import uuid
 uuid.uuid4()

Wenn Sie UUID als Parameter für die URL übergeben müssen, können Sie wie folgt vorgehen:

import uuid
str(uuid.uuid4())

Wenn Sie den Hex-Wert für eine UUID möchten, können Sie den folgenden Wert ausführen:

import uuid    
uuid.uuid4().hex

0

Diese Funktion ist vollständig konfigurierbar und generiert eine eindeutige UID basierend auf dem angegebenen Format

Beispiel: - [8, 4, 4, 4, 12], dies ist das erwähnte Format und es wird die folgende UUID generiert

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

3
UUIDs sind Standard und nicht variabel in der Länge. Das konfigurierbare Generieren einer zufälligen Zeichenfolge kann in einigen Situationen hilfreich sein, in diesem Zusammenhang jedoch nicht. Sie können die Definition unter en.wikipedia.org/wiki/Universally_unique_identifier überprüfen .
Miguelr

2
Vermeiden Sie dies besser, da sonst Kompatibilitätsprobleme auftreten (dies sind keine Standard-GUIDs)
Sylvain Gantois,

-1

2019 Antwort (für Windows):

Wenn Sie eine permanente UUID wünschen, die einen Computer unter Windows eindeutig identifiziert, können Sie diesen Trick verwenden: (Aus meiner Antwort unter https://stackoverflow.com/a/58416992/8874388 kopiert ).

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())

Verwendet die Windows-API, um die permanente UUID des Computers abzurufen, verarbeitet dann die Zeichenfolge, um sicherzustellen, dass es sich um eine gültige UUID handelt, und gibt zuletzt ein Python-Objekt ( https://docs.python.org/3/library/uuid.html ) zurück, mit dem Sie bequem arbeiten können Möglichkeiten zur Verwendung der Daten (z. B. 128-Bit-Ganzzahl, Hex-Zeichenfolge usw.).

Viel Glück!

PS: Der Unterprozessaufruf könnte wahrscheinlich durch ctypes ersetzt werden, die direkt Windows-Kernel / DLLs aufrufen. Aber für meine Zwecke ist diese Funktion alles, was ich brauche. Es führt eine starke Validierung durch und liefert korrekte Ergebnisse.


-1

Überprüfen Sie diesen Beitrag, hat mir sehr geholfen. Kurz gesagt, die beste Option für mich war:

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")) 

Weil ich nur 4-6 zufällige Zeichen anstelle der sperrigen GUID brauchte.


Dies scheint völlig unabhängig von der Frage zu sein, bei der es um UUIDs geht.
Sox mit Monica
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.