Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Tạo GUID trong C#: Guid.NewGuid() và các biến thể

GUID là gì?

GUID (Globally Unique Identifier) - Mã định danh duy nhất toàn cầu. Là số 128-bit (16 bytes) được biểu diễn dưới dạng 32 ký tự hexadecimal, thường nhóm theo dạng 8-4-4-4-12.

Ví dụ: 3F2504E0-4F89-11D3-9A0C-0305E82C3301

Độ duy nhất (Uniqueness)

    2¹²⁸ ≈ 3.4 × 10³⁸
  • Xác suất trùng lặp (collision) cực thấp: ~1 trong 10³⁰ (quintillion) khi sinh 10 tỷ GUID.
  • Đủ an toàn cho distributed systems, database keys, transaction IDs.

Cách tạo GUID cơ bản

using System;

Guid guid = Guid.NewGuid();
Console.WriteLine(guid);  // Ví dụ: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Các overload của Guid.NewGuid()

// 1. Random GUID (Version 4) - Phổ biến nhất
Guid g1 = Guid.NewGuid();

// 2. Tạo từ string (Parse)
Guid g2 = Guid.Parse("3F2504E0-4F89-11D3-9A0C-0305E82C3301");
Guid g3 = Guid.ParseExact("3F2504E04F8911D39A0C0305E82C3301", "N"); // Không dấu gạch ngang

// 3. TryParse (an toàn, không throw exception)
if (Guid.TryParse(input, out Guid result)) 
{
    // Valid GUID
}

// 4. Empty GUID (all zeros)
Guid empty = Guid.Empty; // 00000000-0000-0000-0000-000000000000

Các định dạng chuỗi (ToString formats)


Guid g = Guid.NewGuid();

g.ToString()        // "3f2504e0-4f89-11d3-9a0c-0305e82c3301" (D - default)
g.ToString("D")     // "3f2504e0-4f89-11d3-9a0c-0305e82c3301" (có dấu gạch ngang)
g.ToString("N")     // "3f2504e04f8911d39a0c0305e82c3301" (không dấu gạch ngang)
g.ToString("B")     // "{3f2504e0-4f89-11d3-9a0c-0305e82c3301}" (có ngoặc nhọn)
g.ToString("P")     // "(3f2504e0-4f89-11d3-9a0c-0305e82c3301)" (có ngoặc tròn)
g.ToString("X")     // "{0x3f2504e0,0x4f89,0x11d3,{0x9a,0x0c,0x03,0x05,0xe8,0x2c,0x33,0x01}}"

Các phiên bản GUID (GUID Versions)

VersionTênNguồn entropyDùng cho
V1Time-basedTimestamp + MAC addressSequential, sortable
V2DCE SecurityTimestamp + MAC + POSIX UID/GIDHiếm dùng
V3Name-based (MD5)Namespace + Name (MD5 hash)Deterministic
V4RandomCryptographic RNGPhổ biến nhất (Guid.NewGuid)
V5Name-based (SHA-1)Namespace + Name (SHA-1 hash)Deterministic, bảo mật hơn V3
V6Reordered Time-basedTimestamp reordered + randomSortable + privacy
V7Unix TimestampUnix TS (ms) + randomSortable, modern (RFC 9562)
V8CustomVendor-definedTùy chỉnh

Tạo GUID Version 7 (Timestamp-based, sortable) - .NET 9+


// .NET 9 có sẵn Guid.CreateVersion7()
Guid guidV7 = Guid.CreateVersion7();
// Format: timestamp(48bit) + version(4bit) + variant(2bit) + random(74bit)
// Ưu điểm: Sắp xếp được theo thời gian, tốt cho database index (clustered index)

Tạo GUID Version 7 thủ công (cho .NET < 9)


public static Guid NewGuidV7() 
{
    var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
    var timestampBytes = BitConverter.GetBytes(timestamp);
    if (BitConverter.IsLittleEndian) Array.Reverse(timestampBytes);
    
    var guidBytes = new byte[16];
    Array.Copy(timestampBytes, 2, guidBytes, 0, 6); // 48-bit timestamp
    
    // Random phần còn lại
    RandomNumberGenerator.Fill(guidBytes.AsSpan(6));
    
    // Set version (4 bits at byte 6, high nibble)
    guidBytes[6] = (byte)((guidBytes[6] & 0x0F) | 0x70); // Version 7
    
    // Set variant (2 bits at byte 8, high bits)
    guidBytes[8] = (byte)((guidBytes[8] & 0x3F) | 0x80); // RFC 4122 variant
    
    return new Guid(guidBytes);
}

Ứng dụng thực tế

  • Database Primary Key: Thay thế INT IDENTITY (tránh collision khi merge DB, sharding).
  • Transaction ID: Trace request qua microservices.
  • File naming: Tránh trùng tên khi upload.
  • Correlation ID: Logging, distributed tracing.

Lưu ý hiệu năng

  • Guid.NewGuid() gọi OS RNG (CryptGenRandom / getrandom) - khá nhanh nhưng không miễn phí.
  • Cần sinh hàng triệu GUID/giây? Cân nhắc pool hoặc Sequential GUID (V7).
  • So sánh GUID: dùng guid1 == guid2 (overload operator) hoặc guid1.Equals(guid2).