uuid-java

Hướng dẫn về UUID trong Java

UUID (Universally Unique Identifier) hay còn được gọi là GUID (Globally Unique Identifier) đại diện cho một giá trị cho độ dài 128bit. Để biễu diễn UUID chúng ta thường sử dụng hệ hex (octets) có dạng như sau:

0710a5ca-f57e-11e9-802a-5aa538984bd8

UUID được tạo thành từ các chữ số hex (mỗi chữ số 4 ký tự) cùng với 4 ký hiệu “-”, làm cho độ dài của nó bằng 36 ký tự.

Nil UUID là một dạng UUID đặc biệt, trong đó tất cả các bit được đặt bằng không.

Trong hướng dẫn này, chúng ta sẽ xem xét lớp UUID trong Java. Đầu tiên, chúng ta sẽ xem cách sử dụng chính lớp đó. Sau đó, chúng ta sẽ xem xét các loại UUID khác nhau và cách chúng ta có thể tạo chúng trong Java.

UUID Class

Lớp UUID có một hàm tạo duy nhất:

UUID uuid = new UUID(long mostSignificant64Bits, long leastSignificant64Bits);
Code language: JavaScript (javascript)

Nếu chúng ta muốn sử dụng hàm tạo này, chúng ta cần cung cấp hai giá trị dài. Tuy nhiên, nó yêu cầu chúng ta tự xây dựng mô hình bit cho UUID.

Để thuận tiện, có ba phương pháp tĩnh để tạo UUID.

Phương thức đầu tiên này tạo UUID phiên bản 3 từ mảng byte đã cho:

UUID uuid = UUID.nameUUIDFromBytes(byte[] bytes);

Thứ hai, phương thức randomUUID() tạo ra một UUID phiên bản 4. Đây là cách thuận tiện nhất để tạo UUID:

<strong>UUID</strong> uuid = UUID.randomUUID();
Code language: HTML, XML (xml)

Phương thức tĩnh thứ ba trả về một đối tượng UUID với biểu diễn chuỗi của một UUID nhất định:

UUID uuid = UUID.fromString(String uuidHexDigitString);
Code language: JavaScript (javascript)

Bây giờ chúng ta hãy xem cách một UUID được cấu trúc.

Structure

Hãy lấy ví dụ về UUID:

123e4567-e89b-42d3-a456-556642440000 xxxxxxxx-xxxx-Bxxx-Axxx-xxxxxxxxxxxx

UUID Variant

A đại diện cho biến thể xác định bố cục của UUID. Tất cả các bit khác trong UUID phụ thuộc vào cài đặt của các bit trong trường biến thể. Biến thể được xác định bởi ba bit quan trọng nhất của A:

MSB1 MSB2 MSB3 0 X X reserved (0) 1 0 X current variant (2) 1 1 0 reserved for Microsoft (6) 1 1 1 reserved for future (7)

Giá trị của A trong UUID được đề cập là “a”. Tương đương nhị phân của “a” (= 10xx) hiển thị biến thể là 2.

UUID Version

B đại diện cho phiên bản. Phiên bản trong UUID được đề cập (giá trị của B) là 4.

Java cung cấp các phương pháp để nhận được biến thể và phiên bản của UUID:

<strong>UUID</strong> uuid = UUID.randomUUID(); <strong>int</strong> variant = uuid.variant(); <strong>int</strong> version = uuid.version();
Code language: HTML, XML (xml)

Đây là năm phiên bản khác nhau cho biến thể 2 UUID: Dựa trên thời gian (UUIDv1), DCE Security (UUIDv2), Dựa trên tên (UUIDv3 và UUIDv5) và Ngẫu nhiên (UUIDv4).

Java cung cấp một triển khai cho v3 và v4 nhưng cũng cung cấp một phương thức khởi tạo để tạo bất kỳ loại UUID nào:

<strong>UUID</strong> uuid = new <strong>UUID</strong>(<strong>long</strong> mostSigBits, <strong>long</strong> leastSigBits);
Code language: HTML, XML (xml)

UUID Versions

Version 1

UUID phiên bản 1 dựa trên dấu thời gian hiện tại, được đo bằng đơn vị 100 nano giây từ ngày 15 tháng 10 năm 1582, được nối với địa chỉ MAC của thiết bị nơi UUID được tạo.

Nếu vấn đề riêng tư là vấn đề đáng lo ngại, UUID phiên bản 1 có thể được tạo bằng số 48 bit ngẫu nhiên thay vì địa chỉ MAC. Trong bài viết này, chúng ta sẽ xem xét sự thay thế này.

Đầu tiên, chúng tôi sẽ tạo 64 bit ít nhất và quan trọng nhất dưới dạng giá trị dài:

private static <strong>long</strong> <strong>get64LeastSignificantBitsForVersion1</strong>() { <strong>Random</strong> random = new <strong>Random</strong>(); <strong>long</strong> random63BitLong = random.nextLong() & 0x3FFFFFFFFFFFFFFFL; <strong>long</strong> variant3BitFlag = 0x8000000000000000L; return random63BitLong + variant3BitFlag; } private static <strong>long</strong> <strong>get64MostSignificantBitsForVersion1</strong>() { <strong>LocalDateTime</strong> start = LocalDateTime.of(1582, 10, 15, 0, 0, 0); <strong>Duration</strong> duration = Duration.between(start, LocalDateTime.now()); <strong>long</strong> seconds = duration.getSeconds(); <strong>long</strong> nanos = duration.getNano(); <strong>long</strong> timeForUuidIn100Nanos = seconds * 10000000 + nanos * 100; <strong>long</strong> least12SignificatBitOfTime = (timeForUuidIn100Nanos & 0x000000000000FFFFL) >> 4; <strong>long</strong> version = 1 << 12; return (timeForUuidIn100Nanos & 0xFFFFFFFFFFFF0000L) + version + least12SignificatBitOfTime; }
Code language: PHP (php)

Sau đó, chúng ta có thể chuyển hai giá trị này cho hàm tạo của UUID:

public static UUID <strong>generateType1UUID</strong>() { <strong>long</strong> most64SigBits = get64MostSignificantBitsForVersion1(); <strong>long</strong> least64SigBits = get64LeastSignificantBitsForVersion1(); return new <strong>UUID</strong>(most64SigBits, least64SigBits); }
Code language: HTML, XML (xml)

Version 2

Phiên bản 2 cũng dựa trên dấu thời gian và địa chỉ MAC. Tuy nhiên, RFC 4122 không chỉ định chi tiết thế hệ chính xác, vì vậy chúng tôi sẽ không xem xét cách triển khai trong bài viết này.

Versions 3 and 5

UUID được tạo bằng cách sử dụng hàm băm của không gian tên và tên. Định danh không gian tên là UUID như Hệ thống tên miền (DNS), Định danh đối tượng (OID), URL, v.v.

UUID = hash(NAMESPACE_IDENTIFIER + NAME)

Sự khác biệt duy nhất giữa UUIDv3 và UUIDv5 là Thuật toán băm – v3 sử dụng MD5 (128 bit), trong khi v5 sử dụng SHA-1 (160 bit).

Nói một cách đơn giản, tôi cắt ngắn kết quả băm thành 128 bit và sau đó thay thế 4 bit cho phiên bản và 2 bit cho biến thể.Hãy tạo UUID loại 3:

<strong>byte</strong>[] nameSpaceBytes = bytesFromUUID(namespace); <strong>byte</strong>[] nameBytes = name.getBytes("UTF-8"); <strong>byte</strong>[] result = joinBytes(nameSpaceBytes, nameBytes); <strong>UUID</strong> uuid = UUID.nameUUIDFromBytes(result);
Code language: HTML, XML (xml)

Ở đây, điều quan trọng cần lưu ý là chuỗi hex cho không gian tên trước tiên cần được chuyển đổi thành một mảng byte.

Cuối cùng, Java không cung cấp triển khai cho loại 5. Kiểm tra kho lưu trữ mã nguồn của chúng tôi cho UUIDv5.

Version 4

Việc triển khai UUIDv4 sử dụng số ngẫu nhiên làm nguồn. Việc triển khai Java là SecureRandom, sử dụng một giá trị không thể đoán trước làm hạt giống để tạo ra các số ngẫu nhiên nhằm giảm nguy cơ va chạm.

Hãy tạo UUID phiên bản 4:

<strong>UUID</strong> uuid = UUID.randomUUID();
Code language: HTML, XML (xml)

Hãy tạo một khóa duy nhất bằng cách sử dụng “SHA-256” và một UUID ngẫu nhiên:

<strong>MessageDigest</strong> salt = MessageDigest.getInstance("SHA-256"); salt.update(UUID.randomUUID().toString().getBytes("UTF-8")); <strong>String</strong> digest = bytesToHex(salt.digest());
Code language: HTML, XML (xml)

Tổng kết

Trong bài viết này, chúng ta đã biết cách cấu trúc một UUID và có những biến thể và phiên bản nào. Tôi cũng đã tìm hiểu những phiên bản Java cung cấp triển khai bên ngoài và xem xét các ví dụ mã để tạo các phiên bản khác.

Bài viết liên quan

Leave a Reply

Your email address will not be published.