What a UUID decoder reveals

Every RFC 9562 UUID encodes structural metadata in fixed bit positions. A decoder reads those positions and surfaces:

FieldPosition in stringWhat it tells you
VersionCharacter 13 (first digit of group 3)How the UUID was generated
VariantCharacter 17 (first digit of group 4)Which layout specification it follows
TimestampFirst 48–60 bits (version-dependent)When it was created — v1 and v7 only
Random bitsRemainderPayload data, no decoded meaning

UUID versions and what they expose

Version 4 — random

550e8400-e29b-41d4-a716-446655440000
              ^    ^
              4    a  ← version 4, variant RFC 9562

A v4 UUID carries 122 bits of random data. Beyond the version and variant fields there is nothing to decode — the bits have no semantic meaning.

Version 7 — time-ordered

018c4a14-2d91-7abc-8def-000000000001
^^^^^^^^^^^^^  ^    ^
timestamp      7    8  ← version 7, variant RFC 9562

The first 48 bits (first 12 hex characters) encode a Unix millisecond timestamp:

018c4a14-2d91  →  hex: 018c4a142d91
                  dec: 1700000000401
                  date: 2023-11-14T22:13:20.401Z

Version 1 — MAC address + time

Version 1 encodes a 60-bit timestamp in 100-nanosecond intervals since October 15, 1582. The bits are spread across the first three groups in a non-sequential order (time_low, time_mid, time_hi_and_version), making decoding more involved. It also embeds the MAC address of the generating machine in the last 12 hex characters — a privacy risk that is why v1 should not be used for new work.

How to decode in code

JavaScript — decode version and variant

function decodeUUID(uuid: string): { version: number; variant: string } | null {
  const clean = uuid.replace(/-/g, '');
  if (clean.length !== 32) return null;

  const version = parseInt(clean[12], 16);
  const variantNibble = parseInt(clean[16], 16);

  let variant: string;
  if ((variantNibble & 0b1000) === 0)      variant = 'NCS (legacy)';
  else if ((variantNibble & 0b1100) === 0b1000) variant = 'RFC 9562';
  else if ((variantNibble & 0b1110) === 0b1100) variant = 'Microsoft (legacy)';
  else variant = 'Reserved';

  return { version, variant };
}

JavaScript — extract UUID v7 timestamp

function decodeV7Timestamp(uuid: string): Date | null {
  const clean = uuid.replace(/-/g, '');
  if (clean.length !== 32 || clean[12] !== '7') return null;

  // First 48 bits = 12 hex chars = Unix ms timestamp
  const ms = parseInt(clean.slice(0, 12), 16);
  return new Date(ms);
}

decodeV7Timestamp('018c4a14-2d91-7abc-8def-000000000001');
// → Date: 2023-11-14T22:13:20.401Z

Python

import uuid

def decode_uuid(value: str) -> dict:
    u = uuid.UUID(value)
    return {
        'version': u.version,
        'variant': str(u.variant),
        'int': u.int,
        'hex': u.hex,
    }

# For v7, extract timestamp manually:
def decode_v7_timestamp(value: str) -> int:
    u = uuid.UUID(value)
    assert u.version == 7
    # Top 48 bits are the Unix ms timestamp
    return u.int >> 80

Go

import (
    "github.com/google/uuid"
    "time"
)

func DecodeV7Time(s string) (time.Time, error) {
    u, err := uuid.Parse(s)
    if err != nil {
        return time.Time{}, err
    }
    t, err := u.Time()  // only valid for v1 and v7
    return t, err
}

Bit layout by version

UUID v4 — 128 bits
┌────────────────────────┬────┬──────────────────┬──┬──────────────────────┐
│  random (48 bits)      │ver │  random (12 bits) │var│  random (62 bits)    │
└────────────────────────┴────┴──────────────────┴──┴──────────────────────┘

UUID v7 — 128 bits
┌────────────────────────┬────┬──────────────────┬──┬──────────────────────┐
│  unix_ts_ms (48 bits)  │ver │  rand_a (12 bits) │var│  rand_b (62 bits)    │
└────────────────────────┴────┴──────────────────┴──┴──────────────────────┘
  ↑ sortable timestamp                              ↑ RFC 9562 variant (10xx)

What decoding cannot tell you

Frequently asked questions

What information can you extract from a UUID?

From the UUID string alone you can read the version (digit at position 13) and variant (digit at position 17). For v1 and v7 you can also extract a timestamp — v1 embeds a 60-bit 100-nanosecond timestamp, v7 embeds a 48-bit Unix millisecond timestamp. v4 carries only random bits beyond the version and variant fields.

How do I extract the timestamp from a UUID v7?

Take the first 12 hex characters of the UUID (before the first hyphen, plus the first 4 of the second group), convert to a 48-bit integer, and that value is the Unix timestamp in milliseconds. For example: parseInt(uuid.replace(/-/g, '').slice(0, 12), 16) gives milliseconds since the Unix epoch.

Can you decode a UUID v4 to get the original random bytes?

Yes — the 122 random bits are recoverable from the UUID string itself. Strip the hyphens, parse as hex, then mask out the 4 version bits and 2 variant bits. The result is the 122-bit random payload, though it carries no additional meaning beyond randomness.