.NET
GUID
dashes
programming
software development

Why are there dashes in a .NET GUID?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

The dashes in a .NET GUID (e.g., 550e8400-e29b-41d4-a716-446655440000) are formatting separators defined by RFC 4122 (the UUID standard). They divide the 128-bit value into five groups that correspond to specific fields in the UUID structure: time-low, time-mid, time-hi-and-version, clock-seq, and node. The dashes are part of the string representation only — the underlying data is a 16-byte binary value with no dashes. .NET's Guid.ToString() includes dashes by default, but you can format a GUID without them.

GUID Structure

 
1550e8400-e29b-41d4-a716-446655440000
2│        │    │    │    │
3│        │    │    │    └── Node (48 bits / 12 hex chars)
4│        │    │    └── Clock Sequence (16 bits / 4 hex chars)
5│        │    └── Time High + Version (16 bits / 4 hex chars)
6│        └── Time Mid (16 bits / 4 hex chars)
7└── Time Low (32 bits / 8 hex chars)

The 8-4-4-4-12 grouping is not arbitrary — each section encodes a specific field from the UUID specification.

Version Field

csharp
1var guid = Guid.NewGuid();
2Console.WriteLine(guid);  // e.g., 3f2504e0-4f89-41d3-9a0c-0305e82c3301
3//                                              ^
4//                                              Version 4 (random)

The first digit of the third group indicates the UUID version:

  • 1 = time-based
  • 3 = MD5 hash
  • 4 = random (most common, what Guid.NewGuid() creates)
  • 5 = SHA-1 hash
  • 7 = Unix timestamp-based (newer)

Formatting GUIDs in .NET

csharp
1var guid = Guid.Parse("550e8400-e29b-41d4-a716-446655440000");
2
3// Default — with dashes (D format)
4Console.WriteLine(guid.ToString());
5// 550e8400-e29b-41d4-a716-446655440000
6
7// N format — no dashes, just hex digits
8Console.WriteLine(guid.ToString("N"));
9// 550e8400e29b41d4a716446655440000
10
11// B format — with braces
12Console.WriteLine(guid.ToString("B"));
13// {550e8400-e29b-41d4-a716-446655440000}
14
15// P format — with parentheses
16Console.WriteLine(guid.ToString("P"));
17// (550e8400-e29b-41d4-a716-446655440000)
18
19// X format — hex groups with braces
20Console.WriteLine(guid.ToString("X"));
21// {0x550e8400,0xe29b,0x41d4,{0xa7,0x16,0x44,0x66,0x55,0x44,0x00,0x00}}
FormatExampleUse Case
D (default)550e8400-e29b-...Human-readable, logs, databases
N550e8400e29b...URLs, filenames, compact storage
B{550e8400-e29b-...}Windows Registry, COM
P(550e8400-e29b-...)Some database systems
X{0x550e8400,...}C struct initialization

Creating and Parsing GUIDs

csharp
1// Generate a new random GUID
2var newGuid = Guid.NewGuid();
3
4// Parse from string — all formats work
5var g1 = Guid.Parse("550e8400-e29b-41d4-a716-446655440000");  // D
6var g2 = Guid.Parse("550e8400e29b41d4a716446655440000");       // N
7var g3 = Guid.Parse("{550e8400-e29b-41d4-a716-446655440000}"); // B
8
9// Safe parsing
10if (Guid.TryParse(input, out var parsed))
11{
12    Console.WriteLine(parsed);
13}
14
15// From bytes
16byte[] bytes = new byte[16];
17Random.Shared.NextBytes(bytes);
18var fromBytes = new Guid(bytes);
19
20// To bytes
21byte[] guidBytes = guid.ToByteArray();  // 16 bytes

GUID in Databases

sql
1-- SQL Server stores GUIDs as UNIQUEIDENTIFIER (16 bytes)
2-- Displayed with dashes
3CREATE TABLE Users (
4    Id UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
5    Name NVARCHAR(100)
6);
7
8INSERT INTO Users (Name) VALUES ('Alice');
9SELECT Id FROM Users;
10-- 3F2504E0-4F89-41D3-9A0C-0305E82C3301
11
12-- MySQL uses CHAR(36) or BINARY(16)
13CREATE TABLE Users (
14    Id CHAR(36) DEFAULT (UUID()) PRIMARY KEY,
15    Name VARCHAR(100)
16);
csharp
1// Entity Framework — GUID as primary key
2public class User
3{
4    public Guid Id { get; set; } = Guid.NewGuid();
5    public string Name { get; set; }
6}

GUIDs Without Dashes

csharp
1// For URLs, filenames, or compact formats
2var guid = Guid.NewGuid();
3string compact = guid.ToString("N");  // No dashes
4// "550e8400e29b41d4a716446655440000"
5
6// Base64 encoding (22 chars instead of 32)
7string base64 = Convert.ToBase64String(guid.ToByteArray())
8    .Replace("+", "-")
9    .Replace("/", "_")
10    .TrimEnd('=');
11// "AISNVSvi1EGnFkRmVUQAAA"
csharp
1// URL-safe short GUID
2public static string ToShortGuid(Guid guid)
3{
4    return Convert.ToBase64String(guid.ToByteArray())
5        .Replace("+", "-")
6        .Replace("/", "_")
7        .TrimEnd('=');
8}
9
10public static Guid FromShortGuid(string shortGuid)
11{
12    string base64 = shortGuid.Replace("-", "+").Replace("_", "/") + "==";
13    return new Guid(Convert.FromBase64String(base64));
14}

Why Not Just Remove the Dashes?

The dashes serve readability and validation purposes:

  • Readability: 550e8400-e29b-41d4-a716-446655440000 is easier to visually parse than 550e8400e29b41d4a716446655440000
  • Quick version identification: The third group starts with the version digit (4 in 41d4)
  • Copy-paste accuracy: Dashes help verify you copied the entire GUID
  • Standard compliance: RFC 4122 defines the dashed format as canonical

Common Pitfalls

  • Comparing string representations: "550E8400" and "550e8400" are the same GUID but different strings. Always compare using Guid.Equals() or == on Guid objects, never on string representations.
  • Database storage as strings: Storing GUIDs as CHAR(36) wastes space (36 bytes vs 16 bytes for UNIQUEIDENTIFIER/BINARY(16)). Use the native GUID type or BINARY(16) for efficient storage.
  • Sequential GUIDs for clustered indexes: Random GUIDs (Guid.NewGuid()) cause index fragmentation in SQL Server because inserts scatter across the B-tree. Use NEWSEQUENTIALID() in SQL Server or Guid.CreateVersion7() (.NET 9+) for sequential GUIDs.
  • Byte order confusion: .NET's Guid.ToByteArray() uses mixed-endian format (first three groups are little-endian, last two are big-endian). This differs from RFC 4122's network byte order. Use guid.TryWriteBytes(span, bigEndian: true) in .NET 9+ for standard byte order.
  • Assuming GUIDs are always unique: While the probability of collision is astronomically low (2^122 possible v4 UUIDs), using a weak random generator or creating GUIDs in constrained environments can reduce uniqueness. Always use Guid.NewGuid() which uses a cryptographic random source.

Summary

  • Dashes in GUIDs follow the RFC 4122 standard, dividing the 128-bit value into five meaningful fields
  • The 8-4-4-4-12 format encodes time, version, clock sequence, and node information
  • Use guid.ToString("N") for a dashless 32-character hex string
  • Use guid.ToString("D") (default) for the standard dashed format
  • GUIDs are 16 bytes internally — dashes exist only in the string representation
  • The third group's first hex digit reveals the UUID version (4 = random)

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions