Cara membuat GUID / UUID dengan Python


685

Bagaimana cara membuat GUID dengan Python yang independen terhadap platform? Saya mendengar ada metode menggunakan ActivePython di Windows tetapi Windows hanya karena menggunakan COM. Apakah ada metode menggunakan Python biasa?



34
Untuk cinta semua yang sakral, ini adalah UUID - Universal Unique ID en.wikipedia.org/wiki/Universally_unique_identifier - hanya saja sayangnya MS telah lebih suka GUID.
david.barkhuizen

5
Ini satu liner untuk Anda:python -c 'import uuid; print(uuid.uuid4())'
Ctrl-C

Jawaban:


776

Modul uuid, dengan Python 2.5 dan lebih tinggi, menyediakan pembuatan UUID yang sesuai dengan RFC. Lihat dokumen modul dan RFC untuk detailnya. [ sumber ]

Docs:

Contoh (mengerjakan 2 dan 3):

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

20
Juga, lihatlah shortuuidmodul yang saya tulis, karena memungkinkan Anda untuk menghasilkan UUID yang lebih pendek dan mudah dibaca: github.com/stochastic-technologies/shortuuid
Stavros Korokithakis

2
@StavrosKorokithakis: pernahkah Anda menulis modul shortuuid untuk Python 3.x?
Jay Patel

2
@ JayPatel Apakah shortuuid tidak berfungsi untuk Python 3? Jika tidak, silakan ajukan bug.
Stavros Korokithakis

1
Apa perbedaan antara uuid4().hexdan str(uuid4())?
Kevin

6
Nah, seperti yang Anda lihat di atas, str(uuid4())mengembalikan representasi string UUID dengan tanda hubung termasuk, sementara uuid4().hexmengembalikan "UUID sebagai string heksadesimal 32-karakter"
stuartd

324

Jika Anda menggunakan Python 2.5 atau lebih baru, modul uuid sudah disertakan dengan distribusi standar Python.

Ex:

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

116

Disalin dari: https://docs.python.org/2/library/uuid.html (Karena tautan yang dipasang tidak aktif dan terus diperbarui)

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

Saya menggunakan GUID sebagai kunci acak untuk operasi tipe database.

Bentuk heksadesimal, dengan tanda hubung dan karakter tambahan sepertinya terlalu panjang bagi saya. Tapi saya juga suka bahwa string yang mewakili angka heksadesimal sangat aman karena tidak mengandung karakter yang dapat menyebabkan masalah dalam beberapa situasi seperti '+', '=', dll.

Alih-alih heksadesimal, saya menggunakan string base64 url-safe. Berikut ini tidak sesuai dengan spesifikasi UUID / GUID (selain memiliki jumlah keacakan yang diperlukan).

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
Jika Anda tidak akan repot menggunakannya dalam konteks UUID apa pun, Anda bisa menggunakan random.getrandbits(128).to_bytes(16, 'little')atau (untuk keacakan crypto) os.urandom(16)dan mendapatkan 128 bit acak (UUIDv4 menggunakan 6-7 bit pada info versi). Atau gunakan hanya 15 byte (kehilangan 1-2 bit acak vs UUIDv4) dan menghindari kebutuhan untuk memangkas =tanda - tanda sementara juga mengurangi ukuran yang dikodekan menjadi 20 byte (dari 24, dipangkas menjadi 22), karena setiap kelipatan dari 3 byte encode ke #bytes / 3 * 4base64 karakter tanpa padding diperlukan.
ShadowRanger

@ShadowRanger Ya itulah intinya. 128 bit acak, sesingkat mungkin, sementara URL juga aman. Idealnya hanya menggunakan huruf besar dan kecil dan kemudian angka. Jadi saya kira string base-62.
Chris Dutrow

Ketika saya menggunakan fungsi Anda, saya mendapatkan kesalahan ketik dari returnpernyataan yang mengharapkan objek seperti byte. Itu bisa diperbaiki dengan return str(r_uuid).replace('=','').
Mark Kortink

8

Jika Anda perlu melewati UUID untuk kunci utama untuk model atau bidang unik Anda, maka di bawah ini kode mengembalikan objek UUID -

 import uuid
 uuid.uuid4()

Jika Anda harus melewati UUID sebagai parameter untuk URL yang dapat Anda lakukan seperti kode di bawah ini -

import uuid
str(uuid.uuid4())

Jika Anda ingin nilai hex untuk UUID Anda dapat melakukan yang di bawah ini -

import uuid    
uuid.uuid4().hex

0

Fungsi ini sepenuhnya dapat dikonfigurasi dan menghasilkan cairan unik berdasarkan format yang ditentukan

misalnya: - [8, 4, 4, 4, 12], ini adalah format yang disebutkan dan akan menghasilkan uuid berikut

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
UUID adalah standar, dan tidak panjang variabel. Menghasilkan string acak dengan cara yang dapat dikonfigurasi dapat berguna dalam beberapa situasi, tetapi tidak dalam konteks ini. Anda dapat memeriksa en.wikipedia.org/wiki/Universally_unique_identifier untuk mendapatkan definisi.
miguelr

2
Lebih baik hindari yang ini atau Anda mungkin mengalami masalah kompatibilitas (ini bukan GUID standar)
Sylvain Gantois

-1

2019 Answer (untuk Windows):

Jika Anda menginginkan UUID permanen yang mengidentifikasi mesin secara unik di Windows, Anda dapat menggunakan trik ini: (Disalin dari jawaban saya di 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())

Menggunakan Windows API untuk mendapatkan UUID permanen komputer, lalu memproses string untuk memastikannya adalah UUID yang valid, dan terakhir mengembalikan objek Python ( https://docs.python.org/3/library/uuid.html ) yang memberi Anda kenyamanan cara untuk menggunakan data (seperti integer 128-bit, string hex, dll).

Semoga berhasil!

PS: Panggilan subproses mungkin bisa diganti dengan ctypes yang langsung memanggil Windows kernel / DLL. Tetapi untuk tujuan saya fungsi ini yang saya butuhkan. Itu validasi yang kuat dan menghasilkan hasil yang benar.


-1

Periksa posting ini , banyak membantu saya. Singkatnya, pilihan terbaik bagi saya adalah:

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

Karena saya hanya membutuhkan 4-6 karakter acak daripada GUID besar.


Ini sepertinya sama sekali tidak terkait dengan pertanyaan, yaitu tentang UUID.
sox dengan Monica
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.