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.
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.
Câu trả lời:
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.
reproducible
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. 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.
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)
set_size
là 2 ^ 122, rất lớn .
Đó 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.
NAMESPACE_URL
là 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 .
Tài liệu Postgres mô tả sự khác biệt giữa UUID
s. 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.