Phiên bản UUID nào sẽ sử dụng?


332

Bạn nên sử dụng phiên bản nào của UUID? Tôi đã thấy rất nhiều chủ đề giải thích những gì mỗi phiên bản đòi hỏi, nhưng tôi gặp khó khăn trong việc tìm ra những gì tốt nhất cho các ứng dụng.


2
Lựa chọn của bạn là gì?
Gabe

Bất cứ điều gì làm việc với python. Vì vậy, tôi đoán tài liệu này docs.python.org/2/l Library / uid.html . 1,3,4,5.
user1802143

Nếu bạn tò mò về Phiên bản 3 & 5, hãy xem Câu hỏi này, Tạo v5 UUID. Tên và không gian tên là gì? .
Basil Bourque

Câu trả lời:


414

Có hai cách khác nhau để tạo UUID.

Nếu bạn chỉ cần một ID duy nhất, bạn muốn có phiên bản 1 hoặc phiên bản 4.

  • Phiên bản 1: Điều này tạo ra một ID duy nhất dựa trên địa chỉ MAC của card mạng và bộ hẹn giờ. Những ID này rất dễ dự đoán (được cung cấp, tôi có thể đoán được một ID khác) và có thể được truy ngược lại vào thẻ mạng của bạn. Không nên tạo ra chúng.

  • Phiên bản 4: Chúng được tạo từ các số ngẫu nhiên (hoặc giả ngẫu nhiên). Nếu bạn chỉ cần tạo UUID, đây có thể là những gì bạn muốn.

Nếu bạn cần luôn tạo cùng một UUID từ một tên cụ thể, bạn muốn có phiên bản 3 hoặc phiên bản 5.

  • Phiên bản 3: Điều này tạo ra một ID duy nhất từ ​​hàm băm MD5 của không gian tên và tên. Nếu bạn cần khả năng tương thích ngược (với một hệ thống khác tạo UUID từ tên), hãy sử dụng cái này.

  • Phiên bản 5: Điều này tạo ra một ID duy nhất từ ​​hàm băm SHA-1 của không gian tên và tên. Đây là phiên bản ưa thích.


17
Tôi sẽ thêm: Nếu bạn cần tạo reproducibleUUID từ một tên cụ thể, bạn muốn có phiên bản 3 hoặc phiên bản 5. Nếu bạn cung cấp thuật toán đó cho cùng một đầu vào, nó sẽ tạo ra cùng một đầu ra.
anregen

3
Trong môi trường điện toán đám mây (như AWS hoặc GAE), dường như điểm yếu của Phiên bản 1 đã được giảm nhẹ vào quên lãng. Khi có khả năng có hàng ngàn địa chỉ MAC khác nhau được áp dụng cho trình tạo UUID của một ứng dụng nhất định theo thời gian, loại bỏ khả năng dự đoán và / hoặc truy xuất nguồn gốc.
Buffalo Rabor

3
@ user239558 Với mục tiêu cho một UUID là tính duy nhất của nó, UUIDv5 vẫn có thể được ưu tiên.
Sử thi

7
Nhận xét về Phiên bản 1 là "không được khuyến nghị", quá đơn giản. Trong nhiều tình huống, đây thực sự là tốt và thích hợp hơn. Nhưng nếu bạn lo ngại về bảo mật về việc rò rỉ một trong hai mục thông tin này từ UUID có thể được cung cấp cho các tác nhân không đáng tin cậy: (a) địa chỉ MAC của máy tạo UUID hoặc (b) thời gian khi được tạo, sau đó tránh Phiên bản 1. Nếu hai thông tin đó không nhạy cảm, thì Phiên bản 1 là một cách tuyệt vời để đi.
Basil Bourque

9
Điều gì đã xảy ra với phiên bản 2?
Matthew Woo

53

Nếu bạn muốn một số ngẫu nhiên, sử dụng một thư viện số ngẫu nhiên. Nếu bạn muốn một mã định danh duy nhất có hiệu quả 0,00 ... nhiều 0 nữa ở đây ... 001% khả năng va chạm, bạn nên sử dụng UUIDv1. Xem bài đăng của Nick cho UUIDv3 và v5.

UUIDv1 KHÔNG an toàn. Nó không có nghĩa là được. Nó có nghĩa là ĐỘC ĐÁO, không thể đoán được. UUIDv1 sử dụng dấu thời gian hiện tại, cộng với số nhận dạng máy, cộng với một số công cụ ngẫu nhiên để tạo một số sẽ không bao giờ được tạo bởi thuật toán đó nữa. Điều này phù hợp với ID giao dịch (ngay cả khi mọi người đang thực hiện hàng triệu giao dịch / s).

Thành thật mà nói, tôi không hiểu tại sao UUIDv4 tồn tại ... từ khi đọc RFC4122 , có vẻ như phiên bản đó KHÔNG loại bỏ khả năng va chạm. Nó chỉ là một trình tạo số ngẫu nhiên. Nếu đó là sự thật, thì bạn có cơ hội rất tốt khi hai máy trên thế giới cuối cùng tạo ra cùng một "UUID" v4 (trích dẫn vì không có cơ chế đảm bảo tính ưu việt của U.niversal). Trong tình huống đó, tôi không nghĩ rằng thuật toán thuộc về các phương pháp mô tả RFC để tạo ra các giá trị duy nhất. Nó sẽ thuộc về một RFC về việc tạo ra sự ngẫu nhiên. Đối với một tập hợp các số ngẫu nhiên:

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

67
Bạn sẽ không thấy hai triển khai UUID phiên bản 4 va chạm, trừ khi bạn tạo ra một tỷ UUID mỗi giây trong một thế kỷ giành được một xu lật . Hãy nhớ rằng, set_sizelà 2 ^ 122, rất lớn .
Kevin

8
Thuật toán V4 không nối tiếp, có nghĩa là có khả năng hai UUID đầu tiên được tạo bởi v4 có thể khớp với nhau. Chỉ vì có nhiều tùy chọn, không có nghĩa là bạn phải hết các tùy chọn duy nhất trước khi bạn tạo lặp lại. Điều đó có thể xảy ra bất cứ lúc nào.
anregen

7
Bạn đang không thực sự làm toán. Chúng tôi (như một loài) không tạo ra 1 tỷ UUID mỗi giây. Vì vậy, chúng ta có còn hơn 100 năm cho đến khi va chạm đầu tiên (trung bình).
Kevin

31
V4 "có thể" va chạm, nhưng xác suất cực kỳ thấp mà đối với hầu hết các trường hợp sử dụng, nó có giá trị rủi ro. Re: "hai máy trên thế giới cuối cùng tạo ra cùng một 'UUID'v4", chắc chắn, nhưng đây không phải là vấn đề vì hầu hết các máy trên thế giới sử dụng UUID đều sử dụng chúng trong các bối cảnh khác nhau. Ý tôi là, nếu tôi tạo cùng một UUID cho ứng dụng nội bộ của riêng tôi như bạn làm cho ứng dụng nội bộ của mình, thì điều đó không thành vấn đề. Va chạm chỉ quan trọng nếu chúng xảy ra trong cùng một bối cảnh. (hãy nhớ, ngay cả trong một ứng dụng, nhiều UUID không phải là duy nhất trên toàn bộ ứng dụng, chỉ là bối cảnh chúng được sử dụng)

6
Vì vậy, có vẻ như, nếu bạn không cần Guid của mình an toàn, hãy sử dụng phiên bản 1. Nếu bạn cần bảo mật và cảm thấy may mắn (hoặc thực sự, không cảm thấy không may mắn) hãy sử dụng phiên bản 4.
Vaccano

16

Đó là một câu hỏi rất chung chung. Một câu trả lời là: "nó phụ thuộc vào loại UUID bạn muốn tạo". Nhưng một điều tốt hơn là: "Chà, trước khi tôi trả lời, bạn có thể cho chúng tôi biết lý do tại sao bạn cần mã hóa thuật toán tạo UUID của riêng bạn thay vì gọi chức năng tạo UUID mà hầu hết các hệ điều hành hiện đại cung cấp không?"

Làm điều đó dễ dàng và an toàn hơn, và vì có lẽ bạn không cần phải tự tạo, tại sao phải bận tâm đến việc thực hiện? Trong trường hợp đó, câu trả lời sẽ sử dụng bất cứ điều gì O / S, ngôn ngữ lập trình hoặc khung của bạn cung cấp. Ví dụ: trong Windows, có CoCreateGuid hoặc UuidCreate hoặc một trong các trình bao bọc khác nhau có sẵn từ nhiều khung công tác đang sử dụng. Trong Linux có uuid_generate .

Nếu bạn, vì một số lý do, hoàn toàn cần phải tạo riêng của bạn, thì ít nhất có ý thức tốt để tránh xa việc tạo UUID v1 và v2. Thật khó để có được những điều đó. Thay vào đó, hãy dán UUID v3, v4 hoặc v5.

Cập nhật : Trong một bình luận, bạn đề cập rằng bạn đang sử dụng Python và liên kết đến đây . Nhìn qua giao diện được cung cấp, tùy chọn dễ nhất cho bạn sẽ là tạo UUID v4 (nghĩa là một giao diện được tạo từ dữ liệu ngẫu nhiên) bằng cách gọi uuid.uuid4().

Nếu bạn có một số dữ liệu mà bạn cần (hoặc có thể) băm để tạo UUID từ đó, thì bạn có thể sử dụng v3 (dựa trên MD5) hoặc v5 (dựa trên SHA1). Tạo UUID v3 hoặc v5 rất đơn giản: trước tiên hãy chọn loại UUID bạn muốn tạo (có lẽ bạn nên chọn v5) và sau đó chọn không gian tên thích hợp và gọi hàm với dữ liệu bạn muốn sử dụng để tạo UUID từ đó. Ví dụ: nếu bạn đang băm một URL, bạn sẽ sử dụng NAMESPACE_URL:

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

Xin lưu ý rằng UUID này sẽ khác với UUID v5 cho cùng một URL, được tạo như thế này:

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

Một đặc tính tốt của URL v3 và v5 là chúng phải có khả năng tương tác giữa các lần triển khai. Nói cách khác, nếu hai hệ thống khác nhau đang sử dụng một triển khai tuân thủ RFC4122, thì cả hai sẽ (hoặc ít nhất nên ) tạo ra cùng một UUID nếu tất cả những thứ khác đều bằng nhau (nghĩa là tạo cùng một UUID phiên bản, với cùng một không gian tên và cùng dữ liệu). Thuộc tính này có thể rất hữu ích trong một số trường hợp (đặc biệt là trong các tình huống lưu trữ theo địa chỉ nội dung), nhưng có lẽ không phải trong trường hợp cụ thể của bạn.


4
Tôi đoán đó là vì OP đã không hỏi: làm cách nào để "mã hóa thuật toán tạo UUID của riêng tôi thay vì gọi chức năng tạo UUID mà hầu hết các hệ điều hành hiện đại cung cấp?"
anregen

Bên cạnh đó, tôi nghĩ đó là một lời giải thích tốt về UUIDv3 và v5. Xem câu trả lời của tôi dưới đây về lý do tại sao tôi nghĩ v1 có thể là một lựa chọn tốt.
anregen

NnamPACE_URL là gì? đó là một biến tôi có thể nhận được? từ đâu?
stackdave

@stackdave NAMESPACE_URLlà một UUID thường bằng 6ba7b811-9dad-11d1-80b4-00c04fd430c8, theo khuyến nghị được đưa ra trên trang 30 của RFC-4122 .
Jamie Ridding

2

Tài liệu Postgres mô tả sự khác biệt giữa UUIDs. Một vài trong số họ:

V3:

uuid_generate_v3(namespace uuid, name text) - Hàm này tạo UUID phiên bản 3 trong không gian tên đã cho bằng cách sử dụng tên đầu vào được chỉ định.

V4:

uuid_generate_v4 - Hàm này tạo ra một UUID phiên bản 4, được lấy hoàn toàn từ các số ngẫu nhiên.

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.