UUID เวอร์ชันใดที่จะใช้


332

คุณควรใช้ UUID เวอร์ชันใด ฉันเห็นหลายเธรดอธิบายถึงสิ่งที่แต่ละรุ่นมี แต่ฉันมีปัญหาในการหาสิ่งที่ดีที่สุดสำหรับแอปพลิเคชันใด


2
ตัวเลือกของคุณคืออะไร?
Gabe

อะไรก็ได้ที่ใช้ได้กับงูหลาม ดังนั้นฉันเดาdocs.python.org/2/library/uuid.htmlนี้ 1,3,4,5
user1802143

หากคุณสงสัยเกี่ยวกับรุ่น 3 และ 5 โปรดดูคำถามนี้การสร้าง v5 UUID ชื่อและเนมสเปซคืออะไร? .
Basil Bourque

คำตอบ:


414

มีวิธีการสร้าง UUID สองวิธี

หากคุณต้องการ ID เฉพาะคุณต้องการรุ่น 1 หรือรุ่น 4

  • รุ่น 1: สิ่งนี้จะสร้าง ID ที่ไม่ซ้ำกันตามที่อยู่ MAC ของการ์ดเครือข่ายและตัวจับเวลา รหัสเหล่านี้ง่ายต่อการคาดเดา (จากที่ได้รับฉันอาจคาดเดาได้อีกครั้ง) และสามารถย้อนกลับไปยังการ์ดเครือข่ายของคุณได้ ไม่แนะนำให้สร้างสิ่งเหล่านี้

  • เวอร์ชัน 4: สิ่งเหล่านี้สร้างขึ้นจากตัวเลขสุ่ม (หรือสุ่มหลอก) หากคุณต้องการสร้าง UUID นี่อาจเป็นสิ่งที่คุณต้องการ

หากคุณต้องการสร้าง UUID เดียวกันจากชื่อที่กำหนดคุณต้องการรุ่น 3 หรือรุ่น 5

  • เวอร์ชัน 3: สิ่งนี้สร้าง ID เฉพาะจากแฮช MD5 ของเนมสเปซและชื่อ หากคุณต้องการความเข้ากันได้ย้อนหลัง (ด้วยระบบอื่นที่สร้าง UUID จากชื่อ) ให้ใช้สิ่งนี้

  • เวอร์ชัน 5: สิ่งนี้สร้าง ID เฉพาะจากแฮช SHA-1 ของเนมสเปซและชื่อ นี่เป็นรุ่นที่ต้องการ


17
ฉันจะเพิ่ม: หากคุณต้องการสร้างreproducibleUUID จากชื่อที่กำหนดคุณต้องการเวอร์ชัน 3 หรือ 5 หากคุณฟีดอัลกอริทึมนั้นอินพุตเดียวกันมันจะสร้างผลลัพธ์เดียวกัน
anregen

3
ในสภาพแวดล้อมคลาวด์คอมพิวติ้ง (เช่น AWS หรือ GAE) ดูเหมือนว่าจุดอ่อนของเวอร์ชัน 1 จะถูกลดทอนลงในการให้อภัย ในกรณีที่มีแนวโน้มว่าจะมีที่อยู่ MAC ที่แตกต่างกันหลายพันที่ใช้กับเครื่องกำเนิด UUID ของแอปพลิเคชั่นที่ได้รับเมื่อเวลาผ่านไปกำจัดการคาดการณ์และ / หรือการตรวจสอบ
Buffalo Rabor

3
@ user239558 เนื่องจากเป้าหมายของ UUID คือความเป็นเอกลักษณ์ UUIDv5 ยังคงเป็นที่ต้องการ
Epicurist

7
ความคิดเห็นเกี่ยวกับเวอร์ชั่น 1 ว่า "ไม่แนะนำ" นั้นง่ายเกินไป ในหลาย ๆ สถานการณ์สิ่งเหล่านี้ดีและเป็นที่ต้องการมากกว่า แต่ถ้าคุณมีความกังวลด้านความปลอดภัยเกี่ยวกับการรั่วไหลของข้อมูลเหล่านี้จาก UUID ที่อาจทำให้ผู้ใช้ที่ไม่น่าไว้วางใจ: (a) ที่อยู่ MAC ของเครื่องที่สร้าง UUID หรือ (b) วันที่เวลาที่สร้าง จากนั้นหลีกเลี่ยงเวอร์ชัน 1 หากข้อมูลทั้งสองชิ้นนั้นไม่ละเอียดอ่อนดังนั้นเวอร์ชัน 1 จึงเป็นวิธีที่ยอดเยี่ยม
Basil Bourque

9
เกิดอะไรขึ้นกับเวอร์ชัน 2
Matthew Woo

53

หากคุณต้องการหมายเลขสุ่มให้ใช้ไลบรารีหมายเลขสุ่ม หากคุณต้องการตัวระบุที่ไม่ซ้ำที่มีประสิทธิภาพ 0.00 ... 0 เพิ่มเติมอีกมากมายที่นี่ ... โอกาสในการชนกัน 001% คุณควรใช้ UUIDv1 ดูโพสต์ของ Nick สำหรับ UUIDv3 และ v5

UUIDv1 ไม่ปลอดภัย มันไม่ได้ตั้งใจจะเป็น มันมีความหมายที่จะไม่ซ้ำไม่คาดเดา UUIDv1 ใช้การประทับเวลาปัจจุบันรวมทั้งตัวระบุเครื่องรวมถึงข้อมูลแบบสุ่มบางอย่างเพื่อสร้างตัวเลขที่จะไม่ถูกสร้างขึ้นโดยอัลกอริทึมนั้นอีกครั้ง สิ่งนี้เหมาะสมสำหรับรหัสธุรกรรม (แม้ว่าทุกคนทำธุรกรรมหลายล้านรายการ)

พูดตามตรงฉันไม่เข้าใจว่าทำไม UUIDv4 ถึงมีอยู่ ... จากการอ่านRFC4122ดูเหมือนว่าเวอร์ชั่นนั้นจะไม่ขจัดความเป็นไปได้ที่จะเกิดการชน มันเป็นเพียงเครื่องกำเนิดตัวเลขสุ่ม ถ้านั่นเป็นความจริงมากกว่าที่คุณมีโอกาสที่ดีมากของสองเครื่องในโลกในที่สุดก็สร้าง "UUID" v4 เดียวกัน (เครื่องหมายคำพูดเพราะไม่มีกลไกสำหรับรับประกัน U.niversal U.niversal) ในสถานการณ์นั้นฉันไม่คิดว่าอัลกอริทึมนั้นอยู่ใน RFC ที่อธิบายวิธีการสร้างค่าที่ไม่ซ้ำใคร มันจะอยู่ใน RFC เกี่ยวกับการสร้างแบบสุ่ม สำหรับชุดของตัวเลขสุ่ม:

chance_of_collision = 1 - (set_size! / (set_size - tries)!) / (set_size ^ tries)

67
คุณจะไม่ได้เห็นสองรุ่น UUID 4 การใช้งานชนกันเว้นแต่คุณสร้างพันล้าน UUIDs ทุกวินาทีสำหรับศตวรรษและชนะเหรียญพลิก โปรดจำไว้set_sizeคือ 2 ^ 122 ซึ่งเป็นขนาดใหญ่มาก
เควิน

8
อัลกอริทึม V4 ไม่ใช่อนุกรมหมายความว่ามีโอกาสที่ UUID สองรายการแรกที่สร้างโดย v4 สามารถจับคู่ได้ เพียงเพราะมีตัวเลือกมากมายไม่ได้หมายความว่าคุณต้องใช้ตัวเลือกที่ไม่ซ้ำกันก่อนที่คุณจะสร้างซ้ำ ที่สามารถเกิดขึ้นได้ตลอดเวลา
anregen

7
คุณไม่สามารถทำคณิตศาสตร์ได้จริง เรา (ในฐานะเผ่าพันธุ์) ไม่ได้สร้าง UUID 1 พันล้านทุกวินาที ดังนั้นเราใช้เวลานานกว่า 100 ปีจนถึงการชนครั้งแรก (โดยเฉลี่ย)
เควิน

31
V4 "อาจ" ชนกัน แต่ความน่าจะเป็นนั้นต่ำมากสำหรับผู้ใช้ส่วนใหญ่ความเสี่ยงนั้นคุ้มค่า Re: "สองเครื่องในโลกในที่สุดสร้าง 'UUID'v4 เหมือนกันแน่นอน แต่นี่ไม่ใช่ปัญหาเพราะเครื่องส่วนใหญ่ในโลกที่ใช้ UUID ใช้ในบริบทที่แตกต่างกัน ฉันหมายถึงถ้าฉันสร้าง UUID เดียวกันสำหรับแอพภายในของฉันเองเหมือนกับที่คุณทำกับแอพภายในของคุณมันก็ไม่สำคัญ การชนจะเกิดขึ้นก็ต่อเมื่อเกิดขึ้นในบริบทเดียวกัน (โปรดจำไว้ว่าแม้ในแอพหนึ่ง UUID จำนวนมากไม่จำเป็นต้องมีเอกลักษณ์ในแอพทั้งหมดเพียงแค่บริบทที่ใช้)

6
ดังนั้นดูเหมือนว่าหากคุณไม่ต้องการ Guid ของคุณให้ปลอดภัยให้ใช้เวอร์ชัน 1 หากคุณต้องการความปลอดภัยและรู้สึกโชคดี (หรือจริงๆไม่ต้องรู้สึกโชคร้าย) ใช้เวอร์ชัน 4
Vaccano

16

นั่นเป็นคำถามทั่วไปมาก คำตอบเดียวคือ: "มันขึ้นอยู่กับ UUID ที่คุณต้องการสร้าง" แต่สิ่งที่ดีกว่าคือ: "ก่อนที่ฉันจะตอบคุณช่วยบอกเราได้ไหมว่าทำไมคุณต้องเขียนอัลกอริธึมการสร้าง UUID ของคุณเองแทนที่จะเรียกใช้ฟังก์ชั่นการสร้าง UUID ที่ระบบปฏิบัติการสมัยใหม่ส่วนใหญ่ให้"

การทำนั้นง่ายกว่าและปลอดภัยกว่าและเนื่องจากคุณอาจไม่จำเป็นต้องสร้างของคุณเอง ในกรณีดังกล่าวคำตอบจะกลายเป็นสิ่งที่ O / S ของคุณภาษาการเขียนโปรแกรมหรือกรอบงานให้ ตัวอย่างเช่นใน Windows จะมีCoCreateGuidหรือUuidCreateหรือหนึ่งในเครื่องมือห่อหุ้มที่หลากหลายที่มีให้จากกรอบงานจำนวนมากที่ใช้งานอยู่ ในลินุกซ์มีuuid_generate

หากคุณจำเป็นต้องสร้างของคุณเองด้วยเหตุผลบางประการอย่างน้อยก็ควรที่จะหลีกเลี่ยงการสร้าง UUID v1 และ v2 มันยากที่จะทำให้ถูกต้อง Stick แทนเป็น v3, v4 หรือ v5 UUIDs

ปรับปรุง : ในความคิดเห็นคุณพูดถึงว่าคุณกำลังใช้งูหลามและเชื่อมโยงไปนี้ มองผ่านอินเตอร์เฟซที่มีให้บริการที่ง่ายที่สุดในตัวเลือกสำหรับคุณที่จะสร้าง v4 UUID (นั่นคือหนึ่งที่สร้างขึ้นจากข้อมูลแบบสุ่ม) uuid.uuid4()โดยการเรียก

หากคุณมีข้อมูลบางอย่างที่คุณต้องการแฮช (หรือสามารถ) เพื่อสร้าง UUID จากนั้นคุณสามารถใช้ v3 (ซึ่งต้องอาศัย MD5) หรือ v5 (ซึ่งต้องอาศัย SHA1) การสร้าง v3 หรือ v5 UUID นั้นง่าย: ขั้นแรกเลือกประเภท UUID ที่คุณต้องการสร้าง (คุณควรเลือก v5) จากนั้นเลือกเนมสเปซที่เหมาะสมและเรียกใช้ฟังก์ชันที่มีข้อมูลที่คุณต้องการใช้เพื่อสร้าง UUID ตัวอย่างเช่นหากคุณ hashing URL คุณจะใช้NAMESPACE_URL:

uuid.uuid3(uuid.NAMESPACE_URL, 'https://ripple.com')

โปรดทราบว่า UUID นี้จะแตกต่างจาก v5 UUID สำหรับ URL เดียวกันซึ่งสร้างขึ้นดังนี้:

uuid.uuid5(uuid.NAMESPACE_URL, 'https://ripple.com')

คุณสมบัติที่ดีของ v3 และ v5 URL คือควรจะทำงานร่วมกันระหว่างการนำไปใช้งาน กล่าวอีกนัยหนึ่งถ้าระบบที่แตกต่างกันสองระบบกำลังใช้การติดตั้งที่สอดคล้องกับ RFC4122 พวกเขาจะ (หรืออย่างน้อยควร ) สร้าง UUID เดียวกันถ้าสิ่งอื่น ๆ ทั้งหมดเท่ากัน (เช่นการสร้าง UUID รุ่นเดียวกันด้วยเนมสเปซเดียวกันและ ข้อมูลเดียวกัน) คุณสมบัตินี้มีประโยชน์มากในบางสถานการณ์ (โดยเฉพาะอย่างยิ่งในสถานการณ์การจัดเก็บข้อมูลที่ระบุตำแหน่งเนื้อหา) แต่อาจไม่ได้อยู่ในกรณีเฉพาะของคุณ


4
ฉันเดาว่าเป็นเพราะ OP ไม่ได้ถาม: ฉันจะ "อัพอัลกอริทึมการสร้าง UUID ของฉันเองได้อย่างไรแทนที่จะเรียกใช้ฟังก์ชันการสร้าง UUID ที่ระบบปฏิบัติการสมัยใหม่ส่วนใหญ่มีให้"
anregen

นอกจากนั้นฉันคิดว่ามันเป็นคำอธิบายที่ดีของ UUIDv3 และ v5 ดูคำตอบของฉันด้านล่างเกี่ยวกับสาเหตุที่ฉันคิดว่า v1 เป็นตัวเลือกที่ดี
anregen

NAMESPACE_URL คืออะไร มันเป็นตัวแปรที่ฉันจะได้รับ จากที่ไหน
stackdave

@stackdave NAMESPACE_URLเป็น UUID มักจะเท่ากับ6ba7b811-9dad-11d1-80b4-00c04fd430c8ตามคำแนะนำของที่ทำในหน้า 30 ของRFC-4122
Jamie Ridding

2

เอกสารประกอบของ Postgresอธิบายความแตกต่างระหว่างUUIDs คู่ของพวกเขา:

V3:

uuid_generate_v3(namespace uuid, name text) - ฟังก์ชั่นนี้สร้าง UUID รุ่น 3 ในเนมสเปซที่กำหนดโดยใช้ชื่ออินพุตที่ระบุ

V4:

uuid_generate_v4 - ฟังก์ชั่นนี้สร้าง UUID รุ่น 4 ซึ่งได้มาจากการสุ่มตัวเลข

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