Cách tạo GUID / UUID trong Python


685

Làm cách nào để tạo GUID trong Python độc lập với nền tảng? Tôi nghe nói có một phương pháp sử dụng ActivePython trên Windows nhưng đó chỉ là Windows vì nó sử dụng COM. Có một phương pháp sử dụng Python đơn giản?



34
Vì tình yêu của tất cả những gì thiêng liêng, đó là UUID - ID duy nhất phổ quát en.wikipedia.org/wiki/Universally_unique_identifier - thật không may là MS đã thích GUID hơn.
david.barkhuizen

5
Đây là một lớp lót dành cho bạn:python -c 'import uuid; print(uuid.uuid4())'
Ctrl-C

Câu trả lời:


776

Mô-đun uuid, trong Python 2.5 trở lên, cung cấp thế hệ UUID tuân thủ RFC. Xem tài liệu mô-đun và RFC để biết chi tiết. [ nguồn ]

Tài liệu:

Ví dụ (làm việc trên 2 và 3):

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

20
Ngoài ra, hãy xem shortuuidmô-đun tôi đã viết, vì nó cho phép bạn tạo các UUID ngắn hơn, dễ đọc hơn: github.com/stochastic-technology/shortuuid
Stavros Korokithakis

2
@StavrosKorokithakis: bạn đã viết mô-đun shortuuid cho Python 3.x chưa?
Jay Patel

2
@JayPatel Shortuuid không hoạt động với Python 3? Nếu không, xin vui lòng gửi một lỗi.
Stavros Korokithakis

1
Sự khác biệt giữa uuid4().hexvà là str(uuid4())gì?
Kevin

6
Chà, như bạn có thể thấy ở trên, str(uuid4())trả về một chuỗi đại diện của UUID với các dấu gạch ngang đi kèm, trong khi uuid4().hextrả về "UUID dưới dạng chuỗi thập lục phân 32 ký tự"
stuartd

324

Nếu bạn đang sử dụng Python 2.5 trở lên, mô-đun uuid đã được bao gồm trong phân phối chuẩn Python.

Ví dụ:

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

116

Sao chép từ: https://docs.python.org/2/l Library / uid.html (Vì các liên kết được đăng không hoạt động và chúng tiếp tục cập nhật)

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

Tôi sử dụng GUID làm khóa ngẫu nhiên cho các hoạt động loại cơ sở dữ liệu.

Hình thức thập lục phân, với dấu gạch ngang và các ký tự phụ có vẻ dài không cần thiết đối với tôi. Nhưng tôi cũng thích các chuỗi đại diện cho số thập lục phân rất an toàn ở chỗ chúng không chứa các ký tự có thể gây ra sự cố trong một số tình huống như '+', '=', v.v.

Thay vì thập lục phân, tôi sử dụng chuỗi base64 an toàn url. Những điều sau đây không phù hợp với bất kỳ thông số UUID / GUID nào (ngoài việc có lượng ngẫu nhiên cần thiết).

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
Nếu bạn không bận tâm sử dụng nó trong bất kỳ bối cảnh UUID nào, bạn cũng có thể chỉ sử dụng random.getrandbits(128).to_bytes(16, 'little')hoặc (đối với tính ngẫu nhiên của tiền điện tử) os.urandom(16)và nhận được 128 bit ngẫu nhiên (UUIDv4 sử dụng 6-7 bit trên thông tin phiên bản). Hoặc chỉ sử dụng 15 byte (mất 1-2 bit ngẫu nhiên so với UUIDv4) và tránh phải cắt bớt =các dấu hiệu đồng thời giảm kích thước được mã hóa xuống còn 20 byte (từ 24, được cắt giảm xuống 22), vì bất kỳ bội số 3 byte nào được mã hóa đến #bytes / 3 * 4base64 ký tự mà không cần đệm.
ShadowRanger

@ShadowRanger Vâng, đó là ý tưởng. 128 bit ngẫu nhiên, càng ngắn càng thuận tiện, trong khi cũng an toàn URL. Lý tưởng nhất là nó sẽ chỉ sử dụng chữ in hoa và in thường và sau đó là số. Vì vậy, tôi đoán một chuỗi cơ sở-62.
Chris Dutrow

Khi tôi sử dụng chức năng của bạn, tôi nhận được một lỗi loại từ returncâu lệnh mong đợi một đối tượng giống như byte. Nó có thể được cố định với return str(r_uuid).replace('=','').
Mark Kortink

8

Nếu bạn cần truyền UUID cho khóa chính cho mô hình hoặc trường duy nhất của mình thì mã bên dưới sẽ trả về đối tượng UUID -

 import uuid
 uuid.uuid4()

Nếu bạn cần vượt qua UUID làm tham số cho URL, bạn có thể thực hiện như mã bên dưới -

import uuid
str(uuid.uuid4())

Nếu bạn muốn giá trị hex cho UUID, bạn có thể thực hiện giá trị bên dưới -

import uuid    
uuid.uuid4().hex

0

Chức năng này có thể cấu hình đầy đủ và tạo uid duy nhất dựa trên định dạng được chỉ định

ví dụ: - [8, 4, 4, 4, 12], đây là định dạng được đề cập và nó sẽ tạo ra uuid sau

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 là tiêu chuẩn và không thay đổi về chiều dài. Tạo một chuỗi ngẫu nhiên theo cách có thể định cấu hình có thể hữu ích trong một số trường hợp, nhưng không phải trong bối cảnh này. Bạn có thể kiểm tra en.wikipedia.org/wiki/Universally_unique_identifier để định nghĩa.
Miguelr

2
Tốt hơn nên tránh điều này hoặc bạn có thể gặp phải các vấn đề tương thích (đây không phải là các GUID tiêu chuẩn)
Sylvain Gantois

-1

Trả lời 2019 (dành cho Windows):

Nếu bạn muốn một UUID vĩnh viễn xác định một máy duy nhất trên Windows, bạn có thể sử dụng thủ thuật này: (Sao chép từ câu trả lời của tôi tại 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())

Sử dụng API Windows để lấy UUID vĩnh viễn của máy tính, sau đó xử lý chuỗi để đảm bảo đó là UUID hợp lệ và cuối cùng trả về một đối tượng Python ( https://docs.python.org/3/l Library / uid.html ) giúp bạn thuận tiện cách sử dụng dữ liệu (như số nguyên 128 bit, chuỗi hex, v.v.).

Chúc may mắn!

PS: Cuộc gọi quy trình con có thể được thay thế bằng ctypes gọi trực tiếp kernel / DLL của Windows. Nhưng với mục đích của tôi, chức năng này là tất cả những gì tôi cần. Nó xác nhận mạnh mẽ và tạo ra kết quả chính xác.


-1

Kiểm tra bài này , đã giúp tôi rất nhiều. Nói tóm lại, lựa chọn tốt nhất cho tôi là:

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

Bởi vì tôi chỉ cần 4 - 6 ký tự ngẫu nhiên thay vì GUID cồng kềnh.


Điều này dường như hoàn toàn không liên quan đến câu hỏi, đó là về UUID.
sox với Monica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.