วิธีสร้าง GUID / UUID ใน Python


686

ฉันจะสร้าง GUID ใน Python ที่เป็นอิสระจากแพลตฟอร์มได้อย่างไร ฉันได้ยินว่ามีวิธีการใช้ ActivePython บน Windows แต่เป็น Windows เท่านั้นเนื่องจากใช้ COM มีวิธีการใช้ Python ธรรมดาหรือไม่?



34
สำหรับความรักของทุกสิ่งที่ศักดิ์สิทธิ์มันคือ UUID - Universal Unique ID en.wikipedia.org/wiki/Universally_unique_identifier - มันเป็นเพียงที่ MS โชคดีที่เลือก GUID
david.barkhuizen

5
นี่คือหนึ่งในสายการบินสำหรับคุณ:python -c 'import uuid; print(uuid.uuid4())'
Ctrl-C

คำตอบ:


776

โมดูล uuid ใน Python 2.5 ขึ้นไปให้การสร้าง UUID ที่สอดคล้องกับ RFC ดูเอกสารโมดูลและ RFC สำหรับรายละเอียด [ แหล่งที่มา ]

เอกสาร:

ตัวอย่าง (ทำงานกับ 2 และ 3):

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

20
นอกจากนี้ให้ดูที่shortuuidโมดูลที่ฉันเขียนเพราะจะช่วยให้คุณสร้าง UUID ที่สั้นและอ่านได้: github.com/stochastic-technologies/shortuuid
Stavros Korokithakis

2
@StavrosKorokithakis: คุณได้เขียนโมดูล shortuuid สำหรับ Python 3.x โดยบังเอิญหรือไม่?
Jay Patel

2
@JayPatel shortuuid ใช้งานไม่ได้กับ Python 3 หรือไม่ ถ้าไม่ได้โปรดยื่นข้อผิดพลาด
Stavros Korokithakis

1
ความแตกต่างระหว่างuuid4().hexและstr(uuid4())คืออะไร
เควิน

6
อย่างที่คุณเห็นด้านบนstr(uuid4())ส่งคืนการแทนค่าสตริงของ UUID ด้วยเครื่องหมายขีดกลางที่รวมอยู่ในขณะที่uuid4().hexส่งกลับ"The UUID เป็นสตริงเลขฐานสิบหก 32 ตัวอักษร"
stuartd

324

หากคุณใช้ Python 2.5 หรือใหม่กว่าโมดูล uuidจะรวมอยู่ในการแจกแจงมาตรฐานของ Python แล้ว

Ex:

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

116

คัดลอกมาจาก: 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')

28

ฉันใช้ 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('=', '')

2
หากคุณไม่ต้องการใช้มันในบริบท 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 * 4base64 อักขระโดยไม่ต้องมีการเสริมเต็ม
ShadowRanger

@ShadowRanger ใช่นั่นเป็นความคิด 128 บิตสุ่มสั้นที่สุดเท่าที่จะเป็นไปได้ในขณะที่ยังปลอดภัย URL โดยหลักการแล้วมันจะใช้ตัวอักษรตัวพิมพ์ใหญ่และเล็กเท่านั้น ดังนั้นฉันจึงคาดเดาสตริง -62
Chris Dutrow

เมื่อฉันใช้ฟังก์ชั่นของคุณฉันได้รับข้อผิดพลาดประเภทจากreturnคำสั่งคาดหวังวัตถุคล้ายไบต์ return str(r_uuid).replace('=','')มันสามารถแก้ไขด้วย
Mark Kortink

8

หากคุณต้องการส่งผ่าน UUID สำหรับคีย์หลักสำหรับรุ่นหรือฟิลด์ที่ไม่ซ้ำกันรหัสด้านล่างจะส่งคืนวัตถุ UUID -

 import uuid
 uuid.uuid4()

หากคุณต้องการผ่าน UUID เป็นพารามิเตอร์สำหรับ URL คุณสามารถทำเช่นรหัสด้านล่าง -

import uuid
str(uuid.uuid4())

หากคุณต้องการค่าฐานสิบหกสำหรับ UUID คุณสามารถทำด้านล่างหนึ่ง -

import uuid    
uuid.uuid4().hex

0

ฟังก์ชันนี้สามารถกำหนดค่าได้อย่างสมบูรณ์และสร้าง 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

3
UUID เป็นมาตรฐานและไม่เปลี่ยนแปลงความยาว การสร้างสตริงแบบสุ่มในวิธีที่กำหนดค่าได้จะมีประโยชน์ในบางสถานการณ์ แต่ไม่ได้อยู่ในบริบทนี้ คุณสามารถตรวจสอบคำจำกัดความของen.wikipedia.org/wiki/Universally_unique_identifier
miguelr

2
ดีกว่าหลีกเลี่ยงปัญหานี้หรือคุณอาจพบปัญหาความเข้ากันได้ (นี่ไม่ใช่ GUID มาตรฐาน)
Sylvain Gantois

-1

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 ที่เรียก Windows kernel / DLLs โดยตรง แต่สำหรับวัตถุประสงค์ของฉันฟังก์ชั่นนี้เป็นสิ่งที่ฉันต้องการ มันตรวจสอบที่แข็งแกร่งและสร้างผลลัพธ์ที่ถูกต้อง


-1

ตรวจสอบโพสต์นี้ช่วยฉันได้มาก ในระยะสั้นตัวเลือกที่ดีที่สุดสำหรับฉันคือ:

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 ขนาดใหญ่


ดูเหมือนว่าจะไม่เกี่ยวข้องกับคำถามทั้งหมดซึ่งเป็นเรื่องเกี่ยวกับ UUID
กับโมนิก้า
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.