Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

idt (ID Tool) is a fast, ergonomic CLI tool for working with various identifier formats. Whether you need to generate, inspect, convert, or validate IDs, idt provides a unified interface for all your identifier needs.

Key Features

  • Multi-format Support: Work with UUID (all versions), ULID, NanoID, Snowflake, and more
  • Generate IDs: Create new identifiers with customizable options
  • Inspect IDs: Decode and analyze any supported ID format
  • Convert Formats: Transform IDs between different encodings (hex, base64, base58, etc.)
  • Validate IDs: Check if strings are valid identifiers
  • Compare IDs: Analyze relationships between IDs (chronological, binary, lexicographic)
  • Pipe-friendly: Designed for shell scripting and Unix pipelines
  • JSON Output: Machine-readable output for integration with other tools

Quick Example

# Generate a UUIDv7 (time-sortable)
$ idt gen uuidv7
019c04e5-6118-7b22-95cb-a10e84dad469

# Inspect the generated ID
$ idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469
UUIDV7
  019c04e5-6118-7b22-95cb-a10e84dad469

  Time (UTC)          2026-01-28T13:57:47.416Z
  Local Time (+09:00) 2026-01-28T22:57:47.416+09:00
  Version             7
  Variant             RFC4122
  Random              62 bits

  Hex                 019c04e561187b2295cba10e84dad469
  Base64              AZwE5WEYeyKVy6EOhNrUaQ==
  Int                 2139325608653621017571381452845274217

# Convert to different formats
$ idt convert 019c04e5-6118-7b22-95cb-a10e84dad469 -f base64
AZwE5WEYeyKVy6EOhNrUaQ==

Why idt?

Working with different ID formats often requires multiple tools or libraries. idt consolidates these into a single, fast CLI tool that:

  1. Auto-detects ID types - No need to specify the format when inspecting or converting
  2. Provides rich metadata - Extract timestamps, version info, and other embedded data
  3. Supports modern formats - UUIDv7, ULID, and other time-sortable IDs
  4. Integrates with your workflow - JSON output, stdin support, and Unix-friendly design

Supported ID Types

TypeSortableTimestampBitsDescription
UUIDv1NoYes128Timestamp + MAC address
UUIDv4NoNo128Random
UUIDv6YesYes128Reordered timestamp
UUIDv7YesYes128Unix timestamp + random
ULIDYesYes128Crockford Base32, lexicographically sortable
NanoIDNoNo~126Compact URL-friendly ID
SnowflakeYesYes64Twitter/Discord-style distributed ID

See the ID Types Overview for complete details on all supported formats.

Getting Started

Ready to start using idt? Head to the Installation guide to get set up, then check out the Quick Start for common usage patterns.

Installation

Using Cargo

# Install from crates.io
cargo install idt

# Install from git repository
cargo install --git https://github.com/sh-cho/idt

Build from Source

Clone the repository and build:

git clone https://github.com/sh-cho/idt.git
cd idt
cargo install --path .

Using Homebrew

brew install sh-cho/tap/idt

# or
brew tap sh-cho/tap
brew install idt

Next Steps

Now that you have idt installed, head to the Quick Start guide to learn the basics.

Quick Start

This guide covers the essential idt commands to get you productive quickly.

Generating IDs

Generate IDs with the gen command:

# Generate a random UUID (v4)
idt gen uuid

# Generate a time-sortable UUIDv7
idt gen uuidv7

# Generate a ULID
idt gen ulid

# Generate a NanoID
idt gen nanoid

# Generate a Snowflake ID
idt gen snowflake

# Generate multiple IDs
idt gen uuid -n 10

Inspecting IDs

Analyze any ID with the inspect command:

# Inspect a UUID
idt inspect 550e8400-e29b-41d4-a716-446655440000

# Inspect a ULID
idt inspect 01ARZ3NDEKTSV4RRFFQ69G5FAV

# Auto-detection works for most formats
idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469

Example output:

UUIDV7
  019c04e5-6118-7b22-95cb-a10e84dad469

  Time (UTC)          2026-01-28T13:57:47.416Z
  Local Time (+09:00) 2026-01-28T22:57:47.416+09:00
  Version             7
  Variant             RFC4122
  Random              62 bits

  Hex                 019c04e561187b2295cba10e84dad469
  Base64              AZwE5WEYeyKVy6EOhNrUaQ==
  Int                 2139325608653621017571381452845274217

Converting Formats

Convert IDs to different encodings:

# Convert to hexadecimal
idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex

# Convert to Base64
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64

# Convert to Base58
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base58

# Convert to integer
idt convert 550e8400-e29b-41d4-a716-446655440000 -f int

Validating IDs

Check if a string is a valid ID:

# Validate any ID
idt validate 550e8400-e29b-41d4-a716-446655440000

# Validate as specific type
idt validate -t uuid 550e8400-e29b-41d4-a716-446655440000

# Strict validation (canonical form only)
idt validate --strict 550e8400-e29b-41d4-a716-446655440000

Comparing IDs

Compare two IDs to understand their relationship:

idt compare 019c04e5-6118-7b22-95cb-a10e84dad469 019c04e5-6119-7000-8000-000000000000

This shows binary, lexicographic, and chronological comparisons.

Using JSON Output

Get machine-readable JSON output for any command:

# JSON output
idt gen uuid --json

# Pretty-printed JSON
idt inspect 550e8400-e29b-41d4-a716-446655440000 --json --pretty

Piping and Scripting

idt works great with Unix pipes:

# Generate and immediately inspect
idt gen uuid | idt inspect

# Validate multiple IDs
idt gen ulid -n 100 | idt validate

# Convert piped input
echo "550e8400-e29b-41d4-a716-446655440000" | idt convert -f base64

Getting Help

View available commands and options:

# General help
idt --help

# Help for a specific command
idt gen --help
idt inspect --help

Next Steps

Commands Overview

idt provides six main commands for working with identifiers:

CommandAliasDescription
gengGenerate new IDs
inspectiAnalyze and decode IDs
convertcConvert between formats
validatevCheck if input is valid
compare-Compare two IDs
info-Show ID type information

Global Options

These options work with all commands:

OptionDescription
-j, --jsonOutput in JSON format
-p, --prettyPretty-print JSON output
--no-colorDisable colored output
-h, --helpShow help information
-V, --versionShow version

Command Aliases

For faster typing, use command aliases:

idt g uuid      # Same as: idt gen uuid
idt i <ID>      # Same as: idt inspect <ID>
idt c <ID> -f hex   # Same as: idt convert <ID> -f hex
idt v <ID>      # Same as: idt validate <ID>

Reading from stdin

Most commands that accept IDs can read from stdin:

# Pipe from another command
idt gen uuid | idt inspect

# Read from file
cat ids.txt | idt validate

# Here-string
idt inspect <<< "550e8400-e29b-41d4-a716-446655440000"

Exit Codes

Commands use standard exit codes:

CodeMeaning
0Success
1Error (invalid input, validation failure, etc.)

This makes idt suitable for use in scripts:

if idt validate -q "$ID"; then
    echo "Valid ID"
else
    echo "Invalid ID"
fi

gen - Generate IDs

Generate new identifiers of various types.

Usage

idt gen <TYPE> [OPTIONS]

Arguments

ArgumentDescription
TYPEID type to generate (uuid, uuidv7, ulid, nanoid, snowflake, etc.)

Options

OptionDescription
-n, --count <N>Number of IDs to generate (default: 1)
-f, --format <FORMAT>Output encoding format
-o, --output <FILE>Write output to file
--no-newlineDon’t print trailing newline (single ID only)

UUID Options

OptionDescription
--uuid-version <V>UUID version (1, 4, 6, 7)
--namespace <NS>Namespace for UUID v3/v5 (dns, url, oid, x500, or UUID)
--name <NAME>Name for UUID v3/v5

NanoID Options

OptionDescription
--alphabet <CHARS>Custom alphabet
--length <N>Custom length (default: 21)

Snowflake Options

OptionDescription
--epoch <MS>Custom epoch in milliseconds (or “twitter”/“discord”)
--machine-id <N>Machine/worker ID (0-31)
--datacenter-id <N>Datacenter ID (0-31)

TypeID Options

OptionDescription
--prefix <PREFIX>Type prefix for TypeID

Supported Types

TypeAliasDescription
uuid-UUIDv4 (random) by default
uuidv1-UUIDv1 (timestamp + MAC)
uuidv4-UUIDv4 (random)
uuidv6-UUIDv6 (reordered timestamp)
uuidv7-UUIDv7 (Unix timestamp + random)
uuid-nil-Nil UUID (all zeros)
uuid-max-Max UUID (all ones)
ulid-ULID
nanoid-NanoID
snowflake-Snowflake ID

Examples

Basic Generation

# Generate a random UUID (v4)
idt gen uuid

# Generate UUIDv7 (time-sortable)
idt gen uuidv7

# Generate ULID
idt gen ulid

# Generate NanoID
idt gen nanoid

# Generate Snowflake ID
idt gen snowflake

Multiple IDs

# Generate 10 UUIDs
idt gen uuid -n 10

# Generate 100 ULIDs
idt gen ulid -n 100

UUID Versions

# UUIDv1 (timestamp-based)
idt gen uuidv1

# UUIDv6 (reordered timestamp)
idt gen uuidv6

# UUIDv7 (Unix timestamp)
idt gen uuidv7

# Or use --uuid-version flag
idt gen uuid --uuid-version 7

NanoID Customization

# Custom length
idt gen nanoid --length 32

# Custom alphabet (hex characters only)
idt gen nanoid --alphabet "0123456789abcdef"

# Both
idt gen nanoid --length 16 --alphabet "0123456789ABCDEF"

Snowflake Customization

# Discord epoch
idt gen snowflake --epoch discord

# Twitter epoch
idt gen snowflake --epoch twitter

# Custom epoch (milliseconds since Unix epoch)
idt gen snowflake --epoch 1420070400000

# With machine and datacenter IDs
idt gen snowflake --machine-id 1 --datacenter-id 2

Output Formats

# Generate and output as hex
idt gen uuid -f hex

# Generate and output as Base64
idt gen uuidv7 -f base64

# Save to file
idt gen uuid -n 1000 -o uuids.txt

JSON Output

# Single ID as JSON
idt gen uuid --json
# Output: {"id":"550e8400-e29b-41d4-a716-446655440000"}

# Multiple IDs as JSON array
idt gen uuid -n 3 --json
# Output: ["550e8400-...", "6ba7b810-...", "7c9e6679-..."]

Without Trailing Newline

# Useful for scripting
ID=$(idt gen uuid --no-newline)
echo "Generated: $ID"

inspect - Analyze IDs

Analyze and decode identifiers to extract embedded information like timestamps, versions, and other metadata.

Usage

idt inspect [OPTIONS] [ID]...

Arguments

ArgumentDescription
IDID(s) to inspect (reads from stdin if omitted)

Options

OptionDescription
-t, --type <TYPE>Hint the ID type (skip auto-detection)
-q, --quietOnly show errors (for validation use)

Output Fields

When inspecting an ID, idt displays:

FieldDescription
TypeDetected ID type (e.g., UUIDV7, ULID)
CanonicalThe ID in its canonical format
Time (UTC)Embedded timestamp in UTC (if available)
Local TimeTimestamp in local timezone with UTC offset (if available)
VersionUUID version number (for UUIDs)
VariantUUID variant (for UUIDs)
RandomNumber of random bits
HexHexadecimal encoding
Base64Base64 encoding
IntInteger representation

Examples

Basic Inspection

# Inspect a UUID
idt inspect 550e8400-e29b-41d4-a716-446655440000

# Inspect a ULID
idt inspect 01ARZ3NDEKTSV4RRFFQ69G5FAV

# Inspect multiple IDs
idt inspect 550e8400-e29b-41d4-a716-446655440000 01ARZ3NDEKTSV4RRFFQ69G5FAV

Example Output

$ idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469
UUIDV7
  019c04e5-6118-7b22-95cb-a10e84dad469

  Time (UTC)          2026-01-28T13:57:47.416Z
  Local Time (+09:00) 2026-01-28T22:57:47.416+09:00
  Version             7
  Variant             RFC4122
  Random              62 bits

  Hex                 019c04e561187b2295cba10e84dad469
  Base64              AZwE5WEYeyKVy6EOhNrUaQ==
  Int                 2139325608653621017571381452845274217

ULID Output

$ idt inspect 01ARZ3NDEKTSV4RRFFQ69G5FAV
ULID
  01ARZ3NDEKTSV4RRFFQ69G5FAV

  Time (UTC)          2016-07-30T23:54:10.259Z
  Local Time (+09:00) 2016-07-31T08:54:10.259+09:00
  Random              80 bits

  Hex                 01563e3ab5d3d6764c61efb99302bd5b
  Base64              AVY+OrXT1nZMYe+5kwK9Ww==
  Int                 1777027686520646174104517696511196507

Type Hints

When auto-detection is ambiguous, provide a type hint:

# Force interpretation as UUID
idt inspect -t uuid 550e8400e29b41d4a716446655440000

Reading from stdin

# Pipe from gen command
idt gen uuidv7 | idt inspect

# Read multiple IDs from file
cat ids.txt | idt inspect

# Here-string
idt inspect <<< "550e8400-e29b-41d4-a716-446655440000"

JSON Output

# JSON output
idt inspect 550e8400-e29b-41d4-a716-446655440000 --json

# Pretty-printed JSON
idt inspect 550e8400-e29b-41d4-a716-446655440000 --json --pretty

Example JSON output:

{
  "id_type": "uuidv4",
  "canonical": "550e8400-e29b-41d4-a716-446655440000",
  "valid": true,
  "version": "4",
  "variant": "RFC4122",
  "random_bits": 122,
  "encodings": {
    "hex": "550e8400e29b41d4a716446655440000",
    "base64": "VQ6EAOKbQdSnFkRmVUQAAA==",
    "int": "113059749145936325402354257176981405696"
  }
}

For timestamped IDs, additional fields are included:

{
  "timestamp": { "millis": 1706450267416 },
  "timestamp_iso": "2026-01-28T13:57:47.416Z",
  "timestamp_local_iso": "2026-01-28T22:57:47.416+09:00"
}

Quiet Mode

Quiet mode exits with code 0 for valid IDs, 1 for invalid:

if idt inspect -q "$ID" 2>/dev/null; then
    echo "Valid and parseable"
fi

Inspecting Generated IDs

# Generate and inspect in one pipeline
idt gen uuidv7 | idt inspect

# Generate multiple and inspect
idt gen ulid -n 5 | idt inspect

convert - Convert Formats

Convert identifiers between different encoding formats.

Usage

idt convert [OPTIONS] [ID]...

Arguments

ArgumentDescription
IDID(s) to convert (reads from stdin if omitted)

Options

OptionDescription
-t, --type <TYPE>Source ID type (auto-detect if omitted)
-f, --format <FORMAT>Target encoding format
--to <TYPE>Convert to different ID type (if compatible)
-U, --uppercaseUppercase output
-L, --lowercaseLowercase output

Encoding Formats

FormatDescriptionExample
canonicalOriginal format550e8400-e29b-41d4-a716-446655440000
hexHexadecimal550e8400e29b41d4a716446655440000
base32Base32 (RFC 4648)KUHIBAASSNE5JJYWIRDFKRAAAA
base58Base586K8FVbLqP4V8nDqTJNXH6k
base64Base64VQ6EAOKbQdSnFkRmVUQAAA==
base64urlURL-safe Base64VQ6EAOKbQdSnFkRmVUQAAA
bitsBinary string01010101000011101000...
intInteger113059749145936325402354257176981405696
bytesSpace-separated hex bytes55 0e 84 00 e2 9b 41 d4...

Examples

Basic Conversion

# Convert to hex
idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex
# Output: 550e8400e29b41d4a716446655440000

# Convert to Base64
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64
# Output: VQ6EAOKbQdSnFkRmVUQAAA==

# Convert to Base58
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base58
# Output: 6K8FVbLqP4V8nDqTJNXH6k

# Convert to integer
idt convert 550e8400-e29b-41d4-a716-446655440000 -f int
# Output: 113059749145936325402354257176981405696

Case Transformation

# Uppercase hex
idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex -U
# Output: 550E8400E29B41D4A716446655440000

# Lowercase
idt convert 550E8400-E29B-41D4-A716-446655440000 -f hex -L
# Output: 550e8400e29b41d4a716446655440000

Converting ULID

# ULID to hex
idt convert 01ARZ3NDEKTSV4RRFFQ69G5FAV -f hex
# Output: 01563e3ab5d3d6764c61efb99302bd5b

# ULID to Base64
idt convert 01ARZ3NDEKTSV4RRFFQ69G5FAV -f base64
# Output: AVY+OrXT1nZMYe+5kwK9Ww==

Binary Representation

# Convert to binary string
idt convert 550e8400-e29b-41d4-a716-446655440000 -f bits
# Output: 01010101000011101000010000000000111000101001101101000001110101001010011100010110010001000110011001010101010001000000000000000000

# Convert to space-separated bytes
idt convert 550e8400-e29b-41d4-a716-446655440000 -f bytes
# Output: 55 0e 84 00 e2 9b 41 d4 a7 16 44 66 55 44 00 00

URL-Safe Base64

# Standard Base64 (with padding)
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64
# Output: VQ6EAOKbQdSnFkRmVUQAAA==

# URL-safe Base64 (no padding)
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64url
# Output: VQ6EAOKbQdSnFkRmVUQAAA

Reading from stdin

# Pipe from gen
idt gen uuid | idt convert -f base64
# Possible output: dkIwdr8eQ+WS5BaKwkF55g==

# Convert multiple IDs
echo -e "550e8400-e29b-41d4-a716-446655440000\n6ba7b810-9dad-11d1-80b4-00c04fd430c8" | idt convert -f hex
# Output:
# 550e8400e29b41d4a716446655440000
# 6ba7b8109dad11d180b400c04fd430c8

JSON Output

idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex --json
# Output: "550e8400e29b41d4a716446655440000"

Type Hints

For ambiguous inputs, specify the source type:

# Interpret as UUID (no dashes)
idt convert -t uuid 550e8400e29b41d4a716446655440000 -f canonical
# Output: 550e8400-e29b-41d4-a716-446655440000

validate - Validate IDs

Check if input strings are valid identifiers.

Usage

idt validate [OPTIONS] [ID]...

Arguments

ArgumentDescription
IDID(s) to validate (reads from stdin if omitted)

Options

OptionDescription
-t, --type <TYPE>Expected ID type (any valid if omitted)
-q, --quietNo output, only exit code
--strictStrict validation (reject non-canonical forms)

Exit Codes

CodeMeaning
0All IDs are valid
1One or more IDs are invalid

Examples

Basic Validation

# Validate a UUID
idt validate 550e8400-e29b-41d4-a716-446655440000
# Output: 550e8400-e29b-41d4-a716-446655440000: valid (uuidv4)

# Validate a ULID
idt validate 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Output: 01ARZ3NDEKTSV4RRFFQ69G5FAV: valid (ulid)

# Invalid ID
idt validate not-a-valid-id
# Output: not-a-valid-id: invalid
#   Error: Not a recognized ID format

Type-Specific Validation

# Must be a UUID
idt validate -t uuid 550e8400-e29b-41d4-a716-446655440000
# Output: valid (uuid)

# Must be a ULID
idt validate -t ulid 01ARZ3NDEKTSV4RRFFQ69G5FAV
# Output: valid (ulid)

# Wrong type
idt validate -t ulid 550e8400-e29b-41d4-a716-446655440000
# Output: invalid (expected ulid)

Strict Mode

Strict mode rejects non-canonical forms:

# Canonical form - passes
idt validate --strict 550e8400-e29b-41d4-a716-446655440000

# Uppercase - fails strict validation
idt validate --strict 550E8400-E29B-41D4-A716-446655440000
# Output: invalid
#   Error: Non-canonical form
#   Hint: Canonical form: 550e8400-e29b-41d4-a716-446655440000

Quiet Mode

For scripting, use quiet mode to check exit codes only:

# Check if valid
if idt validate -q "$ID"; then
    echo "Valid ID: $ID"
else
    echo "Invalid ID: $ID"
fi

# Validate and continue only if valid
idt validate -q "$ID" && process_id "$ID"

Validating Multiple IDs

# Multiple arguments
idt validate id1 id2 id3

# From file
cat ids.txt | idt validate

# From generated IDs
idt gen uuid -n 100 | idt validate

Helpful Hints

idt provides hints for common mistakes:

# UUID without dashes
idt validate 550e8400e29b41d4a716446655440000
# Output: invalid
#   Hint: Looks like UUID without dashes. Try adding dashes.

# Invalid characters in UUID
idt validate 550e8400-e29b-41d4-a716-44665544000g
# Output: invalid
#   Hint: Check for invalid characters in UUID.

JSON Output

# Single ID
idt validate 550e8400-e29b-41d4-a716-446655440000 --json
# Output: {"input":"550e8400-...","valid":true,"id_type":"uuidv4"}

# Multiple IDs
idt validate id1 id2 --json
# Output: [{"input":"id1",...},{"input":"id2",...}]

Batch Validation

Validate a file of IDs:

# Count valid/invalid
cat ids.txt | idt validate 2>&1 | grep -c "valid"

# Extract only valid IDs
cat ids.txt | while read id; do
    if idt validate -q "$id" 2>/dev/null; then
        echo "$id"
    fi
done

compare - Compare IDs

Compare two identifiers to understand their relationship in terms of binary ordering, lexicographic ordering, and chronological ordering (for time-based IDs).

Usage

idt compare [OPTIONS] <ID1> <ID2>

Arguments

ArgumentDescription
ID1First ID to compare
ID2Second ID to compare

Options

OptionDescription
-t, --type <TYPE>ID type (auto-detect if omitted)

Comparison Types

ComparisonDescription
BinaryByte-by-byte comparison of raw ID data
LexicographicString comparison of canonical forms
ChronologicalTime comparison (for time-based IDs)

Examples

Basic Comparison

idt compare 019c04e5-6118-7b22-95cb-a10e84dad469 019c04e5-6119-7000-8000-000000000000

Output:

Comparing IDs:
  ID 1:                019c04e5-6118-7b22-95cb-a10e84dad469
  ID 2:                019c04e5-6119-7000-8000-000000000000

Comparison Results:
  Binary:              ID1 < ID2
  Lexicographic:       ID1 < ID2
  Chronological:       ID1 is older (created before ID2)
  Time difference:     1.00 seconds

Comparing Different Types

idt compare 01ARZ3NDEKTSV4RRFFQ69G5FAV 01ARZ3NDEKTSV4RRFFQ69G5FAW

When comparing IDs of different types, idt warns you:

idt compare 550e8400-e29b-41d4-a716-446655440000 01ARZ3NDEKTSV4RRFFQ69G5FAV

Output:

Comparing IDs:
  ID 1:                550e8400-e29b-41d4-a716-446655440000
  ID 2:                01ARZ3NDEKTSV4RRFFQ69G5FAV

  Warning: Different types! (uuidv4 vs ulid)

Comparison Results:
  Binary:              ID1 > ID2
  Lexicographic:       ID1 > ID2

Time-Based Comparison

For IDs with timestamps (UUIDv1, UUIDv6, UUIDv7, ULID, Snowflake), idt shows chronological comparison:

# Generate two UUIDv7s with a delay
ID1=$(idt gen uuidv7)
sleep 2
ID2=$(idt gen uuidv7)
idt compare "$ID1" "$ID2"

Output:

Comparison Results:
  Binary:              ID1 < ID2
  Lexicographic:       ID1 < ID2
  Chronological:       ID1 is older (created before ID2)
  Time difference:     2.00 seconds

Comparison Symbols

The output uses comparison symbols:

SymbolMeaning
<ID1 is less than ID2
>ID1 is greater than ID2
=IDs are equal

JSON Output

idt compare id1 id2 --json

Output:

{
  "id1": "019c04e5-6118-7b22-95cb-a10e84dad469",
  "id2": "019c04e5-6119-7000-8000-000000000000",
  "type1": "uuidv7",
  "type2": "uuidv7",
  "binary_order": "less",
  "lexicographic_order": "less",
  "chronological_order": "less",
  "time_diff_ms": 1000,
  "timestamp1": 1706450267416,
  "timestamp2": 1706450268416
}

Use Cases

Verify sortability:

# Check if time-sortable IDs maintain order
idt compare "$OLDER_ID" "$NEWER_ID"
# Should show: ID1 < ID2 for all comparisons

Debug ordering issues:

# When IDs aren't sorting as expected
idt compare "$ID_A" "$ID_B" --json | jq '.binary_order, .lexicographic_order'

Time difference calculation:

# Find time between two events
idt compare "$START_ID" "$END_ID" --json | jq '.time_diff_ms'

info - ID Type Information

Display information about supported ID types, including their characteristics, specifications, and usage notes.

Usage

idt info [TYPE]

Arguments

ArgumentDescription
TYPEID type to get information about (list all if omitted)

Examples

List All Types

idt info

Output:

Supported ID Types
============================================================

UUID Family:
  uuidv1       [T-] Timestamp + MAC address
  uuidv3       [--] MD5 namespace hash
  uuidv4       [--] Random
  uuidv5       [--] SHA-1 namespace hash
  uuidv6       [TS] Reordered timestamp
  uuidv7       [TS] Unix timestamp + random
  uuid-nil     [--] All zeros
  uuid-max     [--] All ones

Modern Sortable IDs:
  ulid         [TS] Crockford Base32, lexicographically sortable
  snowflake    [TS] Twitter/Discord-style distributed ID

Compact IDs:
  nanoid       [--] Compact URL-friendly ID

Use 'idt info <TYPE>' for detailed information.

The flags in brackets indicate:

  • T = Has timestamp
  • S = Sortable
  • - = No/Not applicable

Detailed Type Information

idt info uuidv7

Output:

UUIDV7
============================================================

Unix timestamp + random

Has Timestamp:   Yes
Sortable:        Yes
Bit Length:      128 bits

Example:         019c04e5-6118-7b22-95cb-a10e84dad469

Specification:   https://datatracker.ietf.org/doc/html/rfc9562

Notes:
  - Recommended for new applications needing sortable UUIDs
  - Unix timestamp in milliseconds
  - Compatible with UUID infrastructure

Other Type Examples

idt info ulid

Output:

ULID
============================================================

Crockford Base32, lexicographically sortable

Has Timestamp:   Yes
Sortable:        Yes
Bit Length:      128 bits

Example:         01ARZ3NDEKTSV4RRFFQ69G5FAV

Specification:   https://github.com/ulid/spec

Notes:
  - Case-insensitive (Crockford Base32)
  - Monotonic within same millisecond
  - Compatible with UUID (128-bit)
idt info snowflake

Output:

SNOWFLAKE
============================================================

Twitter/Discord-style distributed ID

Has Timestamp:   Yes
Sortable:        Yes
Bit Length:      64 bits

Example:         1234567890123456789

Specification:   https://en.wikipedia.org/wiki/Snowflake_ID

Notes:
  - Originally designed by Twitter
  - Requires coordination (machine/datacenter IDs)
  - Epoch can be customized

JSON Output

# All types as JSON
idt info --json

# Specific type as JSON
idt info uuidv7 --json

Example JSON output:

{
  "name": "uuidv7",
  "description": "Unix timestamp + random",
  "has_timestamp": true,
  "is_sortable": true,
  "bit_length": 128,
  "example": "019c04e5-6118-7b22-95cb-a10e84dad469",
  "spec_url": "https://datatracker.ietf.org/doc/html/rfc9562",
  "notes": [
    "Recommended for new applications needing sortable UUIDs",
    "Unix timestamp in milliseconds",
    "Compatible with UUID infrastructure"
  ]
}

Querying Capabilities

Use JSON output to query capabilities programmatically:

# List all sortable types
idt info --json | jq '.[] | select(.is_sortable) | .name'

# List all types with timestamps
idt info --json | jq '.[] | select(.has_timestamp) | .name'

# Get bit length of a type
idt info uuidv7 --json | jq '.bit_length'

ID Types Overview

idt supports a wide variety of identifier formats, from the ubiquitous UUID to modern alternatives like ULID and Snowflake IDs.

Quick Comparison

TypeBitsSortableTimestampFormat
UUIDv1128NoYesxxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx
UUIDv4128NoNoxxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx
UUIDv6128YesYesxxxxxxxx-xxxx-6xxx-xxxx-xxxxxxxxxxxx
UUIDv7128YesYesxxxxxxxx-xxxx-7xxx-xxxx-xxxxxxxxxxxx
ULID128YesYes01ARZ3NDEKTSV4RRFFQ69G5FAV
NanoID~126NoNoV1StGXR8_Z5jdHi6B-myT
Snowflake64YesYes1234567890123456789
KSUID160YesYes0ujsswThIGTUYm2K8FjOOfXtY1K
ObjectId96PartialYes507f1f77bcf86cd799439011

Choosing an ID Type

For New Projects

Recommended: UUIDv7 or ULID

Both provide:

  • Time-sortable ordering
  • Embedded timestamps
  • 128-bit uniqueness
  • Wide compatibility

Choose UUIDv7 if you need UUID compatibility (existing databases, APIs). Choose ULID if you want a more compact string representation.

For Distributed Systems

Recommended: Snowflake ID

  • 64-bit (fits in a long integer)
  • Extremely high throughput
  • Guaranteed ordering within a datacenter
  • Requires coordination (machine/datacenter IDs)

For URL-Safe Short IDs

Recommended: NanoID

  • Customizable length and alphabet
  • URL-safe by default
  • No timestamp (pure random)

For Legacy Compatibility

UUIDv4 remains the most widely supported format.

ID Type Categories

UUID Family

The UUID (Universally Unique Identifier) family includes several versions, each with different generation strategies:

Modern Sortable IDs

These formats were designed specifically for modern distributed systems:

  • ULID - Universally Unique Lexicographically Sortable Identifier
  • Snowflake ID - Twitter/Discord-style distributed ID

Compact IDs

Shorter identifiers for specific use cases:

  • NanoID - Compact, URL-friendly identifier

Other Formats

Additional ID formats supported by idt:

Generation Support

Not all ID types can be generated by idt. Here’s what’s supported:

TypeGenerateInspectConvertValidate
UUIDv1YesYesYesYes
UUIDv4YesYesYesYes
UUIDv6YesYesYesYes
UUIDv7YesYesYesYes
UUID-nilYesYesYesYes
UUID-maxYesYesYesYes
ULIDYesYesYesYes
NanoIDYesYesYesYes
SnowflakeYesYesYesYes

Further Reading

UUID Family

UUID (Universally Unique Identifier) is a 128-bit identifier standardized by RFC 4122 and updated by RFC 9562. UUIDs are the most widely used identifier format.

Format

All UUIDs share the same canonical format:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

Where:

  • M indicates the version (1-8)
  • N indicates the variant (usually 8, 9, a, or b for RFC 4122)

Example: 550e8400-e29b-41d4-a716-446655440000

Versions

UUIDv1 - Timestamp + MAC Address

  • Specification: RFC 4122
  • Timestamp: Yes (100-nanosecond intervals since October 15, 1582)
  • Sortable: No (timestamp is split across the ID)
  • Privacy: Contains MAC address
idt gen uuidv1
# Example: 6ba7b810-9dad-11d1-80b4-00c04fd430c8

Structure:

  • Time-low (32 bits)
  • Time-mid (16 bits)
  • Version + Time-high (16 bits)
  • Variant + Clock sequence (16 bits)
  • Node/MAC address (48 bits)

UUIDv3 - MD5 Namespace Hash

  • Specification: RFC 4122
  • Timestamp: No
  • Sortable: No
  • Deterministic: Yes (same namespace + name = same UUID)
# Currently generation is not supported
# Useful for inspecting existing UUIDv3s
idt inspect 5df41881-3aed-3515-88a7-2f4a814cf09e

UUIDv4 - Random

  • Specification: RFC 4122
  • Timestamp: No
  • Sortable: No
  • Random bits: 122

The most commonly used UUID version. Purely random except for version and variant bits.

idt gen uuid
# or
idt gen uuidv4
# Example: 550e8400-e29b-41d4-a716-446655440000

Collision probability: With 122 random bits, you’d need to generate about 2.71 quintillion UUIDs to have a 50% chance of collision.

UUIDv5 - SHA-1 Namespace Hash

  • Specification: RFC 4122
  • Timestamp: No
  • Sortable: No
  • Deterministic: Yes (same namespace + name = same UUID)

Similar to UUIDv3 but uses SHA-1 instead of MD5.

# Currently generation is not supported
# Useful for inspecting existing UUIDv5s
idt inspect 21f7f8de-8051-5b89-8680-0195ef798b6a

UUIDv6 - Reordered Timestamp

  • Specification: RFC 9562
  • Timestamp: Yes (same resolution as v1)
  • Sortable: Yes
  • Privacy: Contains MAC address (like v1)

Reorders v1’s timestamp bits for lexicographic sorting.

idt gen uuidv6
# Example: 1ec9414c-232a-6b00-b3c8-9e6bdeced846

When to use: When you need v1 compatibility but want sortable IDs.

UUIDv7 - Unix Timestamp + Random

  • Specification: RFC 9562
  • Timestamp: Yes (Unix milliseconds)
  • Sortable: Yes
  • Random bits: 62
  • Recommended: Yes, for new applications

The recommended choice for new applications needing sortable UUIDs.

idt gen uuidv7
# Example: 019c04e5-6118-7b22-95cb-a10e84dad469

Structure:

  • Unix timestamp in milliseconds (48 bits)
  • Version (4 bits)
  • Random (12 bits)
  • Variant (2 bits)
  • Random (62 bits)

Advantages:

  • Naturally sorted by creation time
  • Compatible with existing UUID infrastructure
  • No MAC address (privacy-friendly)
  • Sufficient randomness to avoid collisions

UUID-nil - All Zeros

The nil UUID is all zeros, often used as a placeholder or “no value” indicator.

idt gen uuid-nil
# Output: 00000000-0000-0000-0000-000000000000

UUID-max - All Ones

The max UUID is all ones, sometimes used as a sentinel value.

idt gen uuid-max
# Output: ffffffff-ffff-ffff-ffff-ffffffffffff

Inspecting UUIDs

$ idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469
UUIDV7
  019c04e5-6118-7b22-95cb-a10e84dad469

  Time (UTC)          2026-01-28T13:57:47.416Z
  Local Time (+09:00) 2026-01-28T22:57:47.416+09:00
  Version             7
  Variant             RFC4122
  Random              62 bits

  Hex                 019c04e561187b2295cba10e84dad469
  Base64              AZwE5WEYeyKVy6EOhNrUaQ==
  Int                 2139325608653621017571381452845274217

Converting UUIDs

# Remove dashes
idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex

# To Base64
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64

# To integer
idt convert 550e8400-e29b-41d4-a716-446655440000 -f int

Choosing a UUID Version

Use CaseRecommended Version
General purpose, no special requirementsUUIDv4
Need sortable IDsUUIDv7
Deterministic IDs from namesUUIDv5
Legacy system compatibilityUUIDv1
Sortable + v1 compatibilityUUIDv6

Specifications

  • RFC 4122: Original UUID specification (v1-v5)
    • https://datatracker.ietf.org/doc/html/rfc4122
  • RFC 9562: New UUID formats (v6-v8)
    • https://datatracker.ietf.org/doc/html/rfc9562

ULID

ULID (Universally Unique Lexicographically Sortable Identifier) is a 128-bit identifier designed for distributed systems that need sortable, URL-friendly IDs.

Overview

PropertyValue
Bits128
SortableYes
TimestampYes (millisecond precision)
FormatCrockford Base32
Length26 characters

Format

 01ARZ3NDEKTSV4RRFFQ69G5FAV
 |----------|--------------|
  Timestamp      Random
  (48 bits)     (80 bits)

Example: 01ARZ3NDEKTSV4RRFFQ69G5FAV

Characteristics

Time-Sortable

ULIDs sort lexicographically in chronological order:

$ idt gen ulid
01ARZ3NDEKTSV4RRFFQ69G5FAV
$ idt gen ulid
01ARZ3NDEKTSV4RRFFQ69G5FAW

The second ULID will always sort after the first.

Monotonic

Within the same millisecond, ULIDs increment the random component to maintain ordering:

# Generated in same millisecond
01ARZ3NDEKTSV4RRFFQ69G5FAV
01ARZ3NDEKTSV4RRFFQ69G5FAW  # Random incremented
01ARZ3NDEKTSV4RRFFQ69G5FAX  # Random incremented again

Case-Insensitive

ULIDs use Crockford Base32, which is case-insensitive:

# These are equivalent
idt inspect 01ARZ3NDEKTSV4RRFFQ69G5FAV
idt inspect 01arz3ndektsv4rrffq69g5fav

URL-Safe

The Crockford Base32 alphabet excludes ambiguous characters (I, L, O, U) and is URL-safe.

Generation

# Generate a ULID
idt gen ulid

# Generate multiple ULIDs
idt gen ulid -n 10

Inspection

$ idt inspect 01ARZ3NDEKTSV4RRFFQ69G5FAV
ULID
  01ARZ3NDEKTSV4RRFFQ69G5FAV

  Time (UTC)          2016-07-30T23:54:10.259Z
  Local Time (+09:00) 2016-07-31T08:54:10.259+09:00
  Random              80 bits

  Hex                 01563e3ab5d3d6764c61efb99302bd5b
  Base64              AVY+OrXT1nZMYe+5kwK9Ww==
  Int                 1777027686520646174104517696511196507

Conversion

ULID to UUID

ULIDs are 128-bit and can be converted to UUID format:

# Get hex representation (same as UUID without dashes)
idt convert 01ARZ3NDEKTSV4RRFFQ69G5FAV -f hex
# Output: 01563e3ab5d3d6764c61efb99302bd5b

To Other Formats

# Base64
idt convert 01ARZ3NDEKTSV4RRFFQ69G5FAV -f base64

# Integer
idt convert 01ARZ3NDEKTSV4RRFFQ69G5FAV -f int

# Binary
idt convert 01ARZ3NDEKTSV4RRFFQ69G5FAV -f bits

Comparison with UUID

FeatureULIDUUIDv4UUIDv7
Bits128128128
SortableYesNoYes
TimestampYesNoYes
String length263636
Case-sensitiveNoNoNo
URL-safeYesWith encodingWith encoding

When to Use ULID

Good for:

  • Database primary keys (sortable, compact)
  • Distributed systems needing time-ordered IDs
  • URLs and APIs (shorter than UUID)
  • Any use case needing sortable unique IDs

Consider alternatives if:

  • You need UUID compatibility (use UUIDv7)
  • You need sub-millisecond precision
  • You need 64-bit IDs (use Snowflake)

Specification

  • GitHub: https://github.com/ulid/spec

Crockford Base32 Alphabet

0123456789ABCDEFGHJKMNPQRSTVWXYZ

Excludes: I, L, O, U (to avoid confusion with 1, 1, 0, V)

NanoID

NanoID is a tiny, secure, URL-friendly unique string ID generator. It’s designed to be compact while maintaining sufficient uniqueness for most use cases.

Overview

PropertyValue
Default bits~126
SortableNo
TimestampNo
Default length21 characters
CustomizableYes (alphabet and length)

Format

V1StGXR8_Z5jdHi6B-myT
|---------------------|
  21 random characters

Example: V1StGXR8_Z5jdHi6B-myT

Characteristics

URL-Safe

The default alphabet is URL-safe:

A-Za-z0-9_-

No encoding needed when used in URLs.

Compact

At 21 characters, NanoID is shorter than UUID (36 chars) and ULID (26 chars).

Customizable

Both alphabet and length can be customized:

# Custom length
idt gen nanoid --length 32

# Custom alphabet
idt gen nanoid --alphabet "0123456789abcdef"

# Both
idt gen nanoid --length 16 --alphabet "ABCDEFGHIJKLMNOP"

Secure

Uses cryptographically secure random number generation.

Generation

# Default NanoID (21 characters)
idt gen nanoid

# Longer NanoID
idt gen nanoid --length 32

# Multiple NanoIDs
idt gen nanoid -n 10

Custom Alphabets

# Hex characters only
idt gen nanoid --alphabet "0123456789abcdef"

# Numbers only
idt gen nanoid --alphabet "0123456789"

# Lowercase letters only
idt gen nanoid --alphabet "abcdefghijklmnopqrstuvwxyz"

# Alphanumeric (no special chars)
idt gen nanoid --alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

Inspection

$ idt inspect V1StGXR8_Z5jdHi6B-myT
NANOID
  V1StGXR8_Z5jdHi6B-myT

  Hex        ...
  Base64     ...

Note: NanoID doesn’t embed timestamps or other structured data.

Collision Probability

With default settings (21 characters, 64-character alphabet):

  • ~126 bits of entropy
  • For 1% collision probability: ~149 billion IDs
  • For 50% collision probability: ~2.4 trillion IDs

Adjusting for Your Needs

Use this formula to calculate collision probability:

bits = log2(alphabet_size) * length

Examples:

  • 21 chars, 64 alphabet: ~126 bits
  • 32 chars, 64 alphabet: ~192 bits
  • 16 chars, 16 alphabet (hex): ~64 bits

Comparison with Other IDs

FeatureNanoIDUUIDULID
Length213626
SortableNoNo*Yes
TimestampNoNo*Yes
URL-safeYesNoYes
CustomizableYesNoNo

*UUIDv7 has timestamp and sortability

When to Use NanoID

Good for:

  • Short, URL-friendly IDs
  • Client-side ID generation
  • Non-sequential IDs (no ordering needed)
  • Custom ID formats

Consider alternatives if:

  • You need time-sortable IDs (use ULID or UUIDv7)
  • You need to extract timestamps (use ULID or UUIDv7)
  • You need distributed coordination (use Snowflake)
  • You need UUID compatibility (use UUID)

Common Configurations

API Keys

# Long, alphanumeric
idt gen nanoid --length 32 --alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

Short Codes

# 8-character codes (for sharing)
idt gen nanoid --length 8

Numeric IDs

# Numeric only (for phone-friendly codes)
idt gen nanoid --length 6 --alphabet "0123456789"

Specification

  • GitHub: https://github.com/ai/nanoid
  • Collision calculator: https://zelark.github.io/nano-id-cc/

Snowflake ID

Snowflake IDs are 64-bit identifiers designed by Twitter for distributed systems requiring high-throughput, time-sortable ID generation.

Overview

PropertyValue
Bits64
SortableYes
TimestampYes (millisecond precision)
FormatDecimal integer
CoordinationRequired (machine/datacenter IDs)

Format

 1234567890123456789
 |-----------------|
   64-bit integer

Bit Structure (Twitter format)

 0 | 41 bits timestamp | 5 bits DC | 5 bits Worker | 12 bits sequence
FieldBitsDescription
Sign1Always 0 (positive)
Timestamp41Milliseconds since epoch
Datacenter ID50-31
Worker/Machine ID50-31
Sequence120-4095 per millisecond

Characteristics

High Throughput

  • 4096 IDs per millisecond per worker
  • 4,096,000 IDs per second per worker
  • With 32 workers: ~131 million IDs/second

Time-Sortable

IDs generated later have higher values:

$ idt gen snowflake
1234567890123456789
$ idt gen snowflake
1234567890123456790  # Greater value

Compact

64 bits fits in a single long integer in most languages.

Requires Coordination

Unlike UUIDs, Snowflake IDs require assigning machine/datacenter IDs to avoid collisions.

Generation

# Default Snowflake
idt gen snowflake

# With machine ID
idt gen snowflake --machine-id 1

# With datacenter ID
idt gen snowflake --datacenter-id 2

# Both
idt gen snowflake --machine-id 1 --datacenter-id 2

Custom Epochs

Different systems use different epochs:

# Twitter epoch (default): Nov 4, 2010
idt gen snowflake --epoch twitter

# Discord epoch: Jan 1, 2015
idt gen snowflake --epoch discord

# Custom epoch (milliseconds since Unix epoch)
idt gen snowflake --epoch 1420070400000

Environment Variable

Set default epoch via environment:

export IDT_SNOWFLAKE_EPOCH=discord
idt gen snowflake

Inspection

$ idt inspect 1234567890123456789
SNOWFLAKE
  1234567890123456789

  Time (UTC)          2023-01-15T12:34:56.789Z
  Local Time (+09:00) 2023-01-15T21:34:56.789+09:00
  Datacenter   1
  Worker       2
  Sequence     789

  Hex          112210f47de98115
  Base64       ESIQr0fpgRU=
  Int          1234567890123456789

Common Epochs

SystemEpochMilliseconds
TwitterNov 4, 20101288834974657
DiscordJan 1, 20151420070400000
InstagramJan 1, 20111293840000000

Comparison with Other IDs

FeatureSnowflakeUUIDULID
Bits64128128
SortableYesNo*Yes
TimestampYesNo*Yes
CoordinationRequiredNoNo
ThroughputVery highHighHigh

*UUIDv7 has timestamp and sortability

When to Use Snowflake

Good for:

  • High-throughput systems (>100k IDs/second)
  • Distributed databases
  • Systems needing 64-bit IDs
  • Real-time analytics (time-ordered)

Consider alternatives if:

  • You can’t coordinate machine IDs (use ULID)
  • You need 128-bit IDs (use UUID or ULID)
  • You’re generating IDs client-side (use NanoID)

Implementation Notes

Machine ID Assignment

In production, assign machine IDs via:

  • Configuration files
  • Environment variables
  • Service discovery (e.g., ZooKeeper, Consul)
  • Database sequences

Clock Skew

Snowflake IDs are sensitive to clock skew:

  • Use NTP synchronization
  • Some implementations wait for the clock to catch up
  • Consider using UUIDv7 if clock skew is a concern

Epoch Selection

Choose an epoch close to your system’s start:

  • Maximizes the timestamp range
  • Twitter’s epoch gives ~69 years from 2010
  • A 2024 epoch would give ~69 years from 2024

Variants

Different systems use slightly different bit layouts:

SystemTimestampDC/WorkerSequence
Twitter4110 (5+5)12
Discord4210 (5+5)12
Instagram411310

Specification

  • Original announcement: https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake
  • Wikipedia: https://en.wikipedia.org/wiki/Snowflake_ID

Other ID Types

This page covers additional ID types that idt can inspect and work with.

KSUID

K-Sortable Unique Identifier - a 160-bit identifier from Segment.

PropertyValue
Bits160
SortableYes
TimestampYes (second precision)
FormatBase62
Length27 characters

Format

0ujsswThIGTUYm2K8FjOOfXtY1K
|-------------------------|
  27 Base62 characters

Structure

  • Timestamp: 32 bits (seconds since epoch)
  • Payload: 128 bits (random)

Characteristics

  • Second-level timestamp precision
  • 128 bits of randomness
  • Base62 encoding (alphanumeric, case-sensitive)

Specification

https://github.com/segmentio/ksuid


MongoDB ObjectId

MongoDB’s default document identifier.

PropertyValue
Bits96
SortablePartial
TimestampYes (second precision)
FormatHexadecimal
Length24 characters

Format

507f1f77bcf86cd799439011
|----------------------|
  24 hex characters

Structure

  • Timestamp: 32 bits (Unix seconds)
  • Machine identifier: 24 bits
  • Process ID: 16 bits
  • Counter: 24 bits

Inspection

idt inspect 507f1f77bcf86cd799439011

Specification

https://www.mongodb.com/docs/manual/reference/method/ObjectId/


TypeID

Type-prefixed, sortable identifiers.

PropertyValue
Bits128
SortableYes
TimestampYes
FormatPrefix + Base32

Format

user_01h455vb4pex5vsknk084sn02q
|---|-------------------------|
prefix     UUIDv7 in Base32

Characteristics

  • Type prefix for clarity (e.g., user_, order_)
  • UUIDv7 encoded in Base32
  • Type-safe across systems

Specification

https://github.com/jetify-com/typeid


XID

Globally unique, sortable 96-bit identifier.

PropertyValue
Bits96
SortableYes
TimestampYes (second precision)
FormatBase32
Length20 characters

Format

9m4e2mr0ui3e8a215n4g
|------------------|
 20 Base32 characters

Structure

  • Timestamp: 32 bits (Unix seconds)
  • Machine ID: 24 bits
  • Process ID: 16 bits
  • Counter: 24 bits

Characteristics

  • Compact (20 characters)
  • URL-safe
  • Inspired by MongoDB ObjectId

Specification

https://github.com/rs/xid


CUID

Collision-resistant Unique Identifier.

PropertyValue
Bits~128
SortablePartial
TimestampYes
FormatCustom Base36

Format

cjld2cjxh0000qzrmn831i7rn
|-----------------------|
  25+ characters

Structure

  • c prefix
  • Timestamp
  • Counter
  • Client fingerprint
  • Random block

Specification

https://github.com/paralleldrive/cuid


CUID2

Secure, collision-resistant identifier (CUID successor).

PropertyValue
BitsVariable
SortableNo
TimestampNo
FormatBase36
Default length24 characters

Characteristics

  • Cryptographically secure
  • No timestamp (privacy-focused)
  • Configurable length

Specification

https://github.com/paralleldrive/cuid2


TSID

Time-Sorted Unique Identifier.

PropertyValue
Bits64
SortableYes
TimestampYes
FormatBase32 or numeric

Format

0HXNP0P6V80G8 (Base32)
38352658567418876 (numeric)

Structure

  • Timestamp: 42 bits
  • Node: 10 bits
  • Counter: 12 bits

Characteristics

  • 64-bit (fits in long integer)
  • Similar to Snowflake but with different encoding options
  • ~139 years of timestamps

Specification

https://github.com/f4b6a3/tsid-creator


Comparison Table

TypeBitsSortableTimestampLength
KSUID160YesSeconds27
ObjectId96PartialSeconds24
TypeID128YesMillisVariable
XID96YesSeconds20
CUID~128PartialYes25+
CUID2VariableNoNo24
TSID64YesMillis13-17

Support Status

These ID types have varying levels of support in idt:

TypeGenerateInspectConvertValidate
KSUIDPlannedPartialPartialYes
ObjectIdPlannedPartialPartialYes
TypeIDPlannedPartialPartialYes
XIDPlannedPartialPartialYes
CUIDNoPartialPartialYes
CUID2NoPartialPartialYes
TSIDPlannedPartialPartialYes

“Partial” means the feature works for basic cases but may not support all options.

Examples Overview

This section provides practical examples for common idt use cases.

Quick Examples

Generate and Use

# Generate a UUID and store it
ID=$(idt gen uuidv7 --no-newline)
echo "Created resource with ID: $ID"

# Generate and insert into database
idt gen uuid | xargs -I {} psql -c "INSERT INTO items (id) VALUES ('{}')"

Inspect Unknown IDs

# What type of ID is this?
idt inspect 01ARZ3NDEKTSV4RRFFQ69G5FAV

# When was it created?
idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469 --json | jq '.timestamp_iso'

Batch Operations

# Generate 1000 UUIDs to file
idt gen uuid -n 1000 -o uuids.txt

# Validate all IDs in a file
cat ids.txt | idt validate

# Convert a list of IDs
cat uuids.txt | idt convert -f base64

Example Categories

Common Patterns

Database Primary Keys

# Generate sortable primary key
idt gen uuidv7

# Generate for existing UUID column
idt gen uuid

API Tokens

# Long, secure token
idt gen nanoid --length 32

# URL-safe token
idt gen nanoid --alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

Debugging

# Decode ID from logs
idt inspect "01ARZ3NDEKTSV4RRFFQ69G5FAV"

# Compare two IDs for ordering
idt compare "$OLD_ID" "$NEW_ID"

Data Migration

# Convert UUID format for different system
idt convert "550e8400-e29b-41d4-a716-446655440000" -f base64

# Validate IDs before import
cat export.csv | cut -d, -f1 | idt validate

Generating IDs

Examples for generating various types of identifiers.

Basic Generation

UUIDs

# Random UUID (v4) - most common
idt gen uuid

# Time-sortable UUID (v7) - recommended for new projects
idt gen uuidv7

# Timestamp-based UUID (v1)
idt gen uuidv1

# Reordered timestamp UUID (v6)
idt gen uuidv6

Other Formats

# ULID - compact, sortable
idt gen ulid

# NanoID - short, URL-friendly
idt gen nanoid

# Snowflake - 64-bit distributed ID
idt gen snowflake

Batch Generation

# Generate 10 UUIDs
idt gen uuid -n 10

# Generate 1000 ULIDs
idt gen ulid -n 1000

# Generate to file
idt gen uuidv7 -n 10000 -o ids.txt

Customization

NanoID Options

# Custom length (default is 21)
idt gen nanoid --length 16
idt gen nanoid --length 32

# Custom alphabet
idt gen nanoid --alphabet "0123456789"          # Numeric only
idt gen nanoid --alphabet "0123456789abcdef"    # Hex
idt gen nanoid --alphabet "ABCDEFGHIJKLMNOP"    # Uppercase only

# Combined
idt gen nanoid --length 8 --alphabet "0123456789"

Snowflake Options

# With machine/datacenter IDs
idt gen snowflake --machine-id 1 --datacenter-id 2

# With custom epoch
idt gen snowflake --epoch 1420070400000  # Discord epoch

# Named epochs
idt gen snowflake --epoch twitter
idt gen snowflake --epoch discord

Output Formats

Different Encodings

# Generate as hex (no dashes)
idt gen uuid -f hex

# Generate as Base64
idt gen uuidv7 -f base64

# Generate as integer
idt gen ulid -f int

JSON Output

# Single ID as JSON object
idt gen uuid --json
# {"id":"550e8400-e29b-41d4-a716-446655440000"}

# Multiple IDs as JSON array
idt gen uuid -n 5 --json
# ["550e8400-...","6ba7b810-...",...]

# Pretty-printed
idt gen uuid --json --pretty

No Trailing Newline

# Useful for variable assignment
ID=$(idt gen uuid --no-newline)

# For inline use
echo "ID: $(idt gen uuid --no-newline)"

Practical Examples

Database Seeding

# Generate IDs for test data
for i in {1..100}; do
    ID=$(idt gen uuidv7 --no-newline)
    echo "INSERT INTO users (id, name) VALUES ('$ID', 'User $i');"
done

API Key Generation

# Generate secure API keys
idt gen nanoid --length 32 -n 10

# With custom prefix
for i in {1..5}; do
    KEY=$(idt gen nanoid --length 24 --no-newline)
    echo "sk_live_$KEY"
done

File Naming

# Generate unique filename
FILENAME="backup_$(idt gen nanoid --length 8 --no-newline).tar.gz"
tar -czf "$FILENAME" /data

# With timestamp from ULID
ULID=$(idt gen ulid --no-newline)
mv upload.pdf "document_${ULID}.pdf"

Distributed System IDs

# Server 1 (machine-id 1)
idt gen snowflake --machine-id 1

# Server 2 (machine-id 2)
idt gen snowflake --machine-id 2

# Different datacenters
idt gen snowflake --machine-id 1 --datacenter-id 1  # DC 1
idt gen snowflake --machine-id 1 --datacenter-id 2  # DC 2

Verification Codes

# 6-digit numeric code
idt gen nanoid --length 6 --alphabet "0123456789"

# Alphanumeric confirmation code
idt gen nanoid --length 8 --alphabet "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"

Performance

Bulk Generation

# Generate 100,000 IDs efficiently
time idt gen uuid -n 100000 > /dev/null

# Write to file
idt gen uuidv7 -n 1000000 -o million_ids.txt

Parallel Generation

# Use parallel for very large batches
seq 10 | parallel "idt gen uuid -n 100000" > all_ids.txt

Inspecting IDs

Examples for analyzing and decoding identifiers to extract embedded information.

Basic Inspection

Auto-Detection

idt automatically detects the ID type:

# UUID
idt inspect 550e8400-e29b-41d4-a716-446655440000

# ULID
idt inspect 01ARZ3NDEKTSV4RRFFQ69G5FAV

# Snowflake
idt inspect 1234567890123456789

With Type Hint

Force interpretation as a specific type:

# Parse as UUID (even without dashes)
idt inspect -t uuid 550e8400e29b41d4a716446655440000

# Parse as ULID
idt inspect -t ulid 01ARZ3NDEKTSV4RRFFQ69G5FAV

Extracting Information

Timestamps

# Get creation time from UUIDv7
idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469

# Output includes:
#   Time (UTC)          2026-01-28T13:57:47.416Z
#   Local Time (+09:00) 2026-01-28T22:57:47.416+09:00

Using JSON to extract specific fields:

# Get timestamp as ISO string (UTC)
idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469 --json | jq -r '.timestamp_iso'

# Get timestamp in local timezone
idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469 --json | jq -r '.timestamp_local_iso'

# Get timestamp as milliseconds
idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469 --json | jq '.timestamp'

UUID Version and Variant

# Inspect UUID to see version
idt inspect 550e8400-e29b-41d4-a716-446655440000

# Output includes:
#   Version    4
#   Variant    RFC4122

Multiple Encodings

Every inspection shows the ID in multiple formats:

idt inspect 01ARZ3NDEKTSV4RRFFQ69G5FAV

# Output includes:
#   Hex        01563e3ab5d3d6764c61efb99302bd5b
#   Base64     AVY+OrXT1nZMYe+5kwK9Ww==
#   Int        1777027686520646174104517696511196507

Batch Inspection

Multiple Arguments

# Inspect multiple IDs
idt inspect id1 id2 id3

From File

# Inspect all IDs in a file
cat ids.txt | idt inspect

# Only valid IDs
cat ids.txt | idt inspect 2>/dev/null

Pipeline

# Generate and immediately inspect
idt gen uuidv7 | idt inspect

# Inspect IDs from another command
grep -o '[0-9a-f-]\{36\}' logfile.log | idt inspect

JSON Output

Single ID

idt inspect 550e8400-e29b-41d4-a716-446655440000 --json --pretty

Output:

{
  "id_type": "uuidv4",
  "canonical": "550e8400-e29b-41d4-a716-446655440000",
  "version": "4",
  "variant": "RFC4122",
  "random_bits": 122,
  "encodings": {
    "hex": "550e8400e29b41d4a716446655440000",
    "base64": "VQ6EAOKbQdSnFkRmVUQAAA==",
    "int": "113059749145936325402354257176981405696"
  }
}

Extract Specific Fields

# Get ID type
idt inspect "$ID" --json | jq -r '.id_type'

# Get all encodings
idt inspect "$ID" --json | jq '.encodings'

# Get hex representation
idt inspect "$ID" --json | jq -r '.encodings.hex'

Practical Examples

Debug Logging

# Decode ID from error logs
grep "failed.*id:" error.log | awk '{print $NF}' | idt inspect

# Find when an event occurred (UTC)
idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469 --json | jq -r '.timestamp_iso'
# Output: 2026-01-28T13:57:47.416Z

# Find when an event occurred (local time)
idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469 --json | jq -r '.timestamp_local_iso'
# Output: 2026-01-28T22:57:47.416+09:00

Data Analysis

# Analyze IDs from database export
psql -c "SELECT id FROM events" -t | idt inspect --json | jq -r '.timestamp_iso' | sort

# Group by ID type
cat mixed_ids.txt | while read id; do
    TYPE=$(idt inspect "$id" --json 2>/dev/null | jq -r '.id_type')
    echo "$TYPE: $id"
done

Verify ID Properties

# Check if ID is time-sortable
TYPE=$(idt inspect "$ID" --json | jq -r '.id_type')
case "$TYPE" in
    uuidv7|ulid|snowflake) echo "Time-sortable" ;;
    *) echo "Not time-sortable" ;;
esac

# Check if ID has timestamp
if idt inspect "$ID" --json | jq -e '.timestamp' > /dev/null 2>&1; then
    echo "Has timestamp"
else
    echo "No timestamp"
fi

Convert Between Systems

# Get UUID-compatible hex for ULID
idt inspect 01ARZ3NDEKTSV4RRFFQ69G5FAV --json | jq -r '.encodings.hex'
# Can be used as: INSERT INTO uuid_col VALUES('01563e3ab5d3d6764c61efb99302bd5b')

Error Handling

Invalid IDs

# Invalid ID shows error
idt inspect "not-a-valid-id"
# Error parsing 'not-a-valid-id': Not a recognized ID format

# Quiet mode for scripts
if idt inspect -q "$ID" 2>/dev/null; then
    echo "Valid"
else
    echo "Invalid"
fi

Ambiguous IDs

Some strings could be multiple ID types:

# Provide type hint to disambiguate
idt inspect -t uuid "$AMBIGUOUS_ID"

Converting Formats

Examples for converting IDs between different encoding formats.

Basic Conversions

To Hexadecimal

# UUID to hex (removes dashes)
idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex
# Output: 550e8400e29b41d4a716446655440000

# ULID to hex
idt convert 01ARZ3NDEKTSV4RRFFQ69G5FAV -f hex
# Output: 01563e3ab5d3d6764c61efb99302bd5b

To Base64

# Standard Base64
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64
# Output: VQ6EAOKbQdSnFkRmVUQAAA==

# URL-safe Base64 (no padding)
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64url
# Output: VQ6EAOKbQdSnFkRmVUQAAA

To Base58

idt convert 550e8400-e29b-41d4-a716-446655440000 -f base58
# Output: 6K8FVbLqP4V8nDqTJNXH6k

To Integer

idt convert 550e8400-e29b-41d4-a716-446655440000 -f int
# Output: 113059749145936325402354257176981405696

All Formats

ID="550e8400-e29b-41d4-a716-446655440000"

# Each encoding format
idt convert "$ID" -f canonical  # Original format
idt convert "$ID" -f hex        # Hexadecimal
idt convert "$ID" -f base32     # Base32
idt convert "$ID" -f base58     # Base58
idt convert "$ID" -f base64     # Base64
idt convert "$ID" -f base64url  # URL-safe Base64
idt convert "$ID" -f bits       # Binary string
idt convert "$ID" -f int        # Integer
idt convert "$ID" -f bytes      # Space-separated hex bytes

Case Transformation

Uppercase

# Uppercase hex
idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex -U
# Output: 550E8400E29B41D4A716446655440000

Lowercase

# Lowercase (normalize)
idt convert 550E8400-E29B-41D4-A716-446655440000 -f hex -L
# Output: 550e8400e29b41d4a716446655440000

Batch Conversion

Multiple IDs

# Convert multiple IDs
idt convert id1 id2 id3 -f base64

From File

# Convert all IDs in a file
cat uuids.txt | idt convert -f hex

# Save converted IDs
cat uuids.txt | idt convert -f base64 > encoded.txt

Pipeline

# Generate and convert
idt gen uuid | idt convert -f base64

# Convert output from another command
grep -o '[0-9a-f-]\{36\}' logfile.log | idt convert -f hex

Practical Examples

Database Compatibility

# PostgreSQL bytea format
idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex
# Use as: INSERT INTO table (id) VALUES (decode('550e8400...', 'hex'))

# Binary storage
idt convert 550e8400-e29b-41d4-a716-446655440000 -f bytes
# Output: 55 0e 84 00 e2 9b 41 d4 a7 16 44 66 55 44 00 00

URL Encoding

# URL-safe encoding for API calls
ID=$(idt gen uuidv7 --no-newline)
ENCODED=$(echo "$ID" | idt convert -f base64url)
curl "https://api.example.com/item/$ENCODED"

Cross-System Integration

# System A uses UUIDs with dashes
UUID="550e8400-e29b-41d4-a716-446655440000"

# System B uses hex without dashes
HEX=$(idt convert "$UUID" -f hex)
# 550e8400e29b41d4a716446655440000

# System C uses Base64
B64=$(idt convert "$UUID" -f base64)
# VQ6EAOKbQdSnFkRmVUQAAA==

Data Migration

# Convert exported IDs for import
cat export.csv | while IFS=, read id name; do
    NEW_ID=$(idt convert "$id" -f hex)
    echo "$NEW_ID,$name"
done > import.csv

Compact Storage

# Store IDs more compactly
# UUID: 36 chars -> Base64: 24 chars -> Base58: ~22 chars

# Original
550e8400-e29b-41d4-a716-446655440000  # 36 chars

# Base64
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64
VQ6EAOKbQdSnFkRmVUQAAA==              # 24 chars

# Base58
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base58
6K8FVbLqP4V8nDqTJNXH6k                 # 22 chars

Binary Analysis

# View binary representation
idt convert 550e8400-e29b-41d4-a716-446655440000 -f bits
# Output: 01010101000011101000010000000000...

# View byte-by-byte
idt convert 550e8400-e29b-41d4-a716-446655440000 -f bytes
# Output: 55 0e 84 00 e2 9b 41 d4 a7 16 44 66 55 44 00 00

JSON Output

# Get converted value as JSON
idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex --json
# Output: "550e8400e29b41d4a716446655440000"

# Multiple IDs
idt convert id1 id2 -f base64 --json
# Output: ["VQ6E...","6ba7..."]

Type Hints

When auto-detection fails:

# Interpret as UUID
idt convert -t uuid 550e8400e29b41d4a716446655440000 -f canonical
# Output: 550e8400-e29b-41d4-a716-446655440000

Shell Scripting

Examples for integrating idt into shell scripts and Unix pipelines.

Variable Assignment

Basic Assignment

# Generate and store ID
ID=$(idt gen uuid)
echo "Generated ID: $ID"

# Use --no-newline for cleaner assignment
ID=$(idt gen uuidv7 --no-newline)

Multiple IDs

# Store in array (bash)
mapfile -t IDS < <(idt gen uuid -n 10)
echo "First ID: ${IDS[0]}"
echo "Total: ${#IDS[@]}"

Conditional Logic

Validation

# Check if ID is valid
if idt validate -q "$ID" 2>/dev/null; then
    echo "Valid ID: $ID"
else
    echo "Invalid ID: $ID"
    exit 1
fi

Type Checking

# Check ID type
TYPE=$(idt inspect "$ID" --json 2>/dev/null | jq -r '.id_type')
case "$TYPE" in
    uuidv7|ulid)
        echo "Time-sortable ID"
        ;;
    uuidv4)
        echo "Random UUID"
        ;;
    *)
        echo "Other type: $TYPE"
        ;;
esac

Pipelines

Generate and Process

# Generate, convert, and use
idt gen uuidv7 | idt convert -f base64 | xargs echo "Encoded:"

# Generate multiple and filter
idt gen uuid -n 100 | grep '^[0-4]'  # IDs starting with 0-4

Process Files

# Validate IDs from file
cat ids.txt | idt validate

# Convert all IDs in file
cat uuids.txt | idt convert -f hex > hex_ids.txt

# Inspect and extract timestamps
cat ids.txt | idt inspect --json | jq -r '.timestamp_iso'

Chain Commands

# Generate -> Inspect -> Extract
idt gen uuidv7 | idt inspect --json | jq -r '.timestamp_iso'

# Complex pipeline
idt gen ulid -n 1000 | \
    idt inspect --json | \
    jq -r '.encodings.hex' | \
    sort | \
    head -10

Loops

Process Multiple IDs

# Process each ID individually
while read -r id; do
    echo "Processing: $id"
    idt inspect "$id" --json | jq -r '.id_type'
done < ids.txt

Generate with Custom Logic

# Generate IDs with prefixes
for type in user order item; do
    ID=$(idt gen nanoid --length 16 --no-newline)
    echo "${type}_${ID}"
done

Batch Processing

# Process in batches
idt gen uuid -n 1000 | while read -r id; do
    # Process each ID
    echo "INSERT INTO table VALUES ('$id');"
done | psql mydb

Error Handling

Check Exit Codes

# Validate with error handling
if ! idt validate -q "$ID" 2>/dev/null; then
    echo "Error: Invalid ID '$ID'" >&2
    exit 1
fi

Capture Errors

# Capture both output and errors
RESULT=$(idt inspect "$ID" 2>&1)
if [ $? -eq 0 ]; then
    echo "Success: $RESULT"
else
    echo "Error: $RESULT" >&2
fi

Continue on Error

# Process all, report errors
cat ids.txt | while read -r id; do
    if idt validate -q "$id" 2>/dev/null; then
        echo "$id" >> valid.txt
    else
        echo "$id" >> invalid.txt
    fi
done

Practical Scripts

Database Seeding Script

#!/bin/bash
# seed_database.sh - Generate test data with unique IDs

COUNT=${1:-100}
TABLE=${2:-users}

echo "Seeding $TABLE with $COUNT records..."

idt gen uuidv7 -n "$COUNT" | while read -r id; do
    NAME="User_$(idt gen nanoid --length 8 --no-newline)"
    echo "INSERT INTO $TABLE (id, name) VALUES ('$id', '$NAME');"
done | psql mydb

echo "Done!"

ID Migration Script

#!/bin/bash
# migrate_ids.sh - Convert IDs between formats

INPUT_FILE=$1
OUTPUT_FORMAT=${2:-base64}

if [ -z "$INPUT_FILE" ]; then
    echo "Usage: $0 <input_file> [format]"
    exit 1
fi

cat "$INPUT_FILE" | while read -r id; do
    CONVERTED=$(idt convert "$id" -f "$OUTPUT_FORMAT" 2>/dev/null)
    if [ -n "$CONVERTED" ]; then
        echo "$CONVERTED"
    else
        echo "# Failed: $id" >&2
    fi
done

ID Validation Script

#!/bin/bash
# validate_export.sh - Validate IDs in CSV export

FILE=$1
COLUMN=${2:-1}

if [ -z "$FILE" ]; then
    echo "Usage: $0 <csv_file> [column_number]"
    exit 1
fi

TOTAL=0
VALID=0
INVALID=0

tail -n +2 "$FILE" | cut -d',' -f"$COLUMN" | while read -r id; do
    ((TOTAL++))
    if idt validate -q "$id" 2>/dev/null; then
        ((VALID++))
    else
        ((INVALID++))
        echo "Invalid at line $TOTAL: $id" >&2
    fi
done

echo "Total: $TOTAL, Valid: $VALID, Invalid: $INVALID"

Timestamp Extraction Script

#!/bin/bash
# extract_timestamps.sh - Extract creation times from IDs

while read -r id; do
    TIMESTAMP=$(idt inspect "$id" --json 2>/dev/null | jq -r '.timestamp_iso // "N/A"')
    echo "$id -> $TIMESTAMP"
done

Integration with Other Tools

With jq

# Extract specific fields
idt inspect "$ID" --json | jq '{type: .id_type, time: .timestamp_iso}'

# Filter by type
idt gen uuid -n 10 --json | jq '.[]'

With xargs

# Process IDs in parallel
cat ids.txt | xargs -P 4 -I {} sh -c 'idt inspect "{}" --json'

With awk

# Combine with awk processing
idt gen uuid -n 100 | awk '{print NR": "$0}'

With parallel

# High-performance parallel processing
cat large_ids.txt | parallel -j 8 'idt inspect {} --json'

JSON Output

Examples for using idt’s JSON output for machine-readable data processing.

Enabling JSON Output

Basic JSON

# Add --json flag to any command
idt gen uuid --json
idt inspect "$ID" --json
idt validate "$ID" --json
idt compare "$ID1" "$ID2" --json
idt info --json

Pretty-Printed JSON

# Add --pretty for formatted output
idt inspect "$ID" --json --pretty

Command Outputs

gen Command

# Single ID
idt gen uuid --json
# {"id":"550e8400-e29b-41d4-a716-446655440000"}

# Multiple IDs
idt gen uuid -n 3 --json
# ["550e8400-...","6ba7b810-...","7c9e6679-..."]

inspect Command

idt inspect 019c04e5-6118-7b22-95cb-a10e84dad469 --json --pretty

Output:

{
  "id_type": "uuidv7",
  "canonical": "019c04e5-6118-7b22-95cb-a10e84dad469",
  "timestamp": 1706450267416,
  "timestamp_iso": "2026-01-28T13:57:47.416Z",
  "timestamp_local_iso": "2026-01-28T22:57:47.416+09:00",
  "version": "7",
  "variant": "RFC4122",
  "random_bits": 62,
  "encodings": {
    "hex": "019c04e561187b2295cba10e84dad469",
    "base64": "AZwE5WEYeyKVy6EOhNrUaQ==",
    "int": "2139325608653621017571381452845274217"
  }
}

validate Command

idt validate 550e8400-e29b-41d4-a716-446655440000 --json

Output:

{
  "input": "550e8400-e29b-41d4-a716-446655440000",
  "valid": true,
  "id_type": "uuidv4"
}

Invalid ID:

{
  "input": "not-valid",
  "valid": false,
  "error": "Not a recognized ID format"
}

compare Command

idt compare "$ID1" "$ID2" --json --pretty

Output:

{
  "id1": "019c04e5-6118-7b22-95cb-a10e84dad469",
  "id2": "019c04e5-6119-7000-8000-000000000000",
  "type1": "uuidv7",
  "type2": "uuidv7",
  "binary_order": "less",
  "lexicographic_order": "less",
  "chronological_order": "less",
  "time_diff_ms": 1000,
  "timestamp1": 1706450267416,
  "timestamp2": 1706450268416
}

info Command

idt info uuidv7 --json --pretty

Output:

{
  "name": "uuidv7",
  "description": "Unix timestamp + random",
  "has_timestamp": true,
  "is_sortable": true,
  "bit_length": 128,
  "example": "019c04e5-6118-7b22-95cb-a10e84dad469",
  "spec_url": "https://datatracker.ietf.org/doc/html/rfc9562",
  "notes": [
    "Recommended for new applications needing sortable UUIDs",
    "Unix timestamp in milliseconds",
    "Compatible with UUID infrastructure"
  ]
}

Processing with jq

Extract Fields

# Get ID type
idt inspect "$ID" --json | jq -r '.id_type'

# Get timestamp
idt inspect "$ID" --json | jq -r '.timestamp_iso'

# Get specific encoding
idt inspect "$ID" --json | jq -r '.encodings.hex'

Filter and Transform

# Get only sortable types
idt info --json | jq '[.[] | select(.is_sortable)]'

# Extract names of types with timestamps
idt info --json | jq -r '.[] | select(.has_timestamp) | .name'

# Create custom object
idt inspect "$ID" --json | jq '{id: .canonical, created: .timestamp_iso}'

Batch Processing

# Process multiple IDs
cat ids.txt | while read id; do
    idt inspect "$id" --json
done | jq -s '.'  # Combine into array

# Extract timestamps from multiple IDs
cat ids.txt | while read id; do
    idt inspect "$id" --json
done | jq -r '.timestamp_iso'

Integration Examples

Store in Database

# Generate structured data for insertion
idt gen uuidv7 --json | jq -r '
    "INSERT INTO ids (id, created_at) VALUES (\(.id), NOW());"
'

API Integration

# Generate ID and create JSON payload
ID=$(idt gen uuidv7 --no-newline)
PAYLOAD=$(jq -n --arg id "$ID" '{"resource_id": $id, "type": "new"}')
curl -X POST -d "$PAYLOAD" https://api.example.com/resources

Logging

# Structured logging
idt inspect "$ID" --json | jq -c '{
    event: "id_inspected",
    id_type: .id_type,
    timestamp: .timestamp_iso
}'

Configuration Files

# Generate config with new IDs
cat config.template.json | jq --arg id "$(idt gen uuidv7 --no-newline)" '
    .session_id = $id
'

Converting Output

To CSV

# Convert JSON output to CSV
idt info --json | jq -r '
    ["name","has_timestamp","is_sortable","bit_length"],
    (.[] | [.name, .has_timestamp, .is_sortable, .bit_length])
    | @csv
'

To TSV

# Convert to tab-separated
idt info --json | jq -r '.[] | [.name, .description] | @tsv'

To Environment Variables

# Export as env vars
eval $(idt inspect "$ID" --json | jq -r '
    "export ID_TYPE=\(.id_type)",
    "export ID_TIMESTAMP=\(.timestamp_iso // "none")"
')

Error Handling

Check for Errors

# Check if valid JSON was returned
RESULT=$(idt inspect "$ID" --json 2>&1)
if echo "$RESULT" | jq -e . >/dev/null 2>&1; then
    echo "Valid JSON: $RESULT"
else
    echo "Error: $RESULT" >&2
fi

Handle Missing Fields

# Use // for default values
idt inspect "$ID" --json | jq -r '.timestamp_iso // "No timestamp"'

Performance Tips

Avoid Pretty Print in Pipelines

# Fast (compact JSON)
idt gen uuid -n 1000 --json | jq '.[]'

# Slower (pretty printed)
idt gen uuid -n 1000 --json --pretty | jq '.[]'

Use jq Streaming for Large Data

# Stream processing for large datasets
idt gen uuid -n 10000 --json | jq -c '.[]'

Encoding Formats

idt supports various encoding formats for converting and displaying IDs.

Available Formats

FormatDescriptionExample (128-bit UUID)
canonicalOriginal/standard format550e8400-e29b-41d4-a716-446655440000
hexHexadecimal (lowercase)550e8400e29b41d4a716446655440000
base32RFC 4648 Base32KUHIBAASSNE5JJYWIRDFKRAAAA
base58Bitcoin-style Base586K8FVbLqP4V8nDqTJNXH6k
base64Standard Base64VQ6EAOKbQdSnFkRmVUQAAA==
base64urlURL-safe Base64VQ6EAOKbQdSnFkRmVUQAAA
bitsBinary string01010101000011101000...
intInteger representation113059749145936325402354257176981405696
bytesSpace-separated hex bytes55 0e 84 00 e2 9b 41 d4...

Format Details

Canonical

The standard format for each ID type:

  • UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (36 characters)
  • ULID: 26 Crockford Base32 characters
  • NanoID: Variable length (default 21 characters)
  • Snowflake: Decimal integer
idt convert "$ID" -f canonical

Hexadecimal (hex)

Raw bytes as hexadecimal characters (lowercase).

  • Length: 2 characters per byte
  • Characters: 0-9, a-f
  • Use case: Database storage, binary comparison
idt convert 550e8400-e29b-41d4-a716-446655440000 -f hex
# Output: 550e8400e29b41d4a716446655440000

Base32

RFC 4648 Base32 encoding (without padding).

  • Characters: A-Z, 2-7
  • Use case: Case-insensitive encoding, DNS-safe
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base32
# Output: KUHIBAASSNE5JJYWIRDFKRAAAA

Base58

Bitcoin-style Base58 encoding (excludes 0, O, I, l).

  • Characters: 1-9, A-H, J-N, P-Z, a-k, m-z
  • Use case: User-friendly, avoids ambiguous characters
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base58
# Output: 6K8FVbLqP4V8nDqTJNXH6k

Base64

Standard Base64 encoding with padding.

  • Characters: A-Z, a-z, 0-9, +, /, =
  • Use case: Email-safe encoding, general data encoding
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64
# Output: VQ6EAOKbQdSnFkRmVUQAAA==

Base64 URL-safe (base64url)

URL-safe Base64 without padding.

  • Characters: A-Z, a-z, 0-9, -, _
  • Use case: URLs, filenames, HTTP headers
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64url
# Output: VQ6EAOKbQdSnFkRmVUQAAA

Binary (bits)

Binary string representation.

  • Characters: 0, 1
  • Use case: Bit-level analysis, debugging
idt convert 550e8400-e29b-41d4-a716-446655440000 -f bits
# Output: 0101010100001110100001000000000011100010...

Integer (int)

Decimal integer representation.

  • Characters: 0-9
  • Use case: Numeric comparison, database integer columns
idt convert 550e8400-e29b-41d4-a716-446655440000 -f int
# Output: 113059749145936325402354257176981405696

Note: 128-bit IDs produce very large integers that may overflow in some languages.

Bytes

Space-separated hexadecimal bytes.

  • Use case: Byte-level inspection, debugging
idt convert 550e8400-e29b-41d4-a716-446655440000 -f bytes
# Output: 55 0e 84 00 e2 9b 41 d4 a7 16 44 66 55 44 00 00

Comparison Table

FormatLength (128-bit)URL-SafeHuman-Readable
canonical36NoGood
hex32YesFair
base3226YesFair
base58~22YesGood
base6424NoFair
base64url22YesFair
bits128YesPoor
int~39YesPoor
bytes47NoGood

Usage Examples

Convert Command

# Convert to specific format
idt convert "$ID" -f hex
idt convert "$ID" -f base64
idt convert "$ID" -f base58

# With case transformation
idt convert "$ID" -f hex -U    # Uppercase
idt convert "$ID" -f hex -L    # Lowercase

Generate with Format

# Generate in specific format
idt gen uuid -f hex
idt gen uuidv7 -f base64

Inspect Output

The inspect command shows multiple formats automatically:

$ idt inspect 550e8400-e29b-41d4-a716-446655440000
UUIDV4
  550e8400-e29b-41d4-a716-446655440000

  Hex        550e8400e29b41d4a716446655440000
  Base64     VQ6EAOKbQdSnFkRmVUQAAA==
  Int        113059749145936325402354257176981405696

Choosing a Format

Use CaseRecommended Format
Database storagehex or canonical
URLs and APIsbase64url or base58
Display to userscanonical or base58
Compact storagebase58 or base64url
Cross-system compatibilityhex
Debuggingbytes or bits

ID Types Comparison

A comprehensive comparison of all ID types supported by idt.

Quick Reference

TypeBitsSortableTimestampRandom BitsString Length
UUIDv1128NoYes~1436
UUIDv3128NoNo036
UUIDv4128NoNo12236
UUIDv5128NoNo036
UUIDv6128YesYes~6236
UUIDv7128YesYes6236
ULID128YesYes8026
NanoID~126NoNo~12621
Snowflake64YesYes0~19
KSUID160YesYes12827
ObjectId96PartialYes~4024
XID96YesYes~4020
TSID64YesYes~2213-17

Detailed Comparison

Timestamp Precision

TypePrecisionEpoch
UUIDv1100 nanosecondsOctober 15, 1582
UUIDv6100 nanosecondsOctober 15, 1582
UUIDv7MillisecondsUnix epoch (1970)
ULIDMillisecondsUnix epoch (1970)
SnowflakeMillisecondsCustom (e.g., 2010, 2015)
KSUIDSecondsMay 13, 2014
ObjectIdSecondsUnix epoch (1970)
XIDSecondsUnix epoch (1970)
TSIDMillisecondsUnix epoch (1970)

Collision Resistance

TypeSame MillisecondDifferent NodesNotes
UUIDv4ExcellentExcellent122 random bits
UUIDv7GoodExcellent62 random bits + timestamp
ULIDExcellentExcellentMonotonic + 80 random bits
NanoIDExcellentExcellent~126 random bits
SnowflakeLimitedRequires coordination4096/ms per worker

Encoding

TypeEncodingCase SensitiveAlphabet
UUIDHexadecimalNo0-9, a-f
ULIDCrockford Base32No0-9, A-Z (excluding I, L, O, U)
NanoIDCustom (default URL-safe)YesA-Z, a-z, 0-9, -, _
SnowflakeDecimalN/A0-9
KSUIDBase62Yes0-9, A-Z, a-z
ObjectIdHexadecimalNo0-9, a-f
XIDBase32No0-9, a-v

Use Case Recommendations

Database Primary Keys

RequirementRecommended Type
UUID compatibility requiredUUIDv7
Compact storageULID or Snowflake
Time-sortable queriesUUIDv7, ULID, or Snowflake
Maximum randomnessUUIDv4
64-bit integer columnSnowflake or TSID

Distributed Systems

RequirementRecommended Type
No coordination neededUUIDv7, ULID, UUIDv4
Very high throughputSnowflake
Cross-datacenterUUIDv7 or ULID
Compact wire formatSnowflake (64-bit)

User-Facing IDs

RequirementRecommended Type
Short URL slugsNanoID (custom length)
Readable codesNanoID (custom alphabet)
Compact but sortableULID
Standard formatUUID (canonical)

Security-Sensitive

RequirementRecommended Type
Non-sequentialUUIDv4 or NanoID
Hide creation timeUUIDv4 or NanoID
Cryptographic randomnessUUIDv4 or NanoID

Format Conversion Compatibility

Since ULID and UUID are both 128-bit, they can be converted between each other:

# ULID to UUID hex
idt convert 01ARZ3NDEKTSV4RRFFQ69G5FAV -f hex
# Can be stored in UUID column

# UUID to various formats
idt convert 550e8400-e29b-41d4-a716-446655440000 -f base64

Storage Size Comparison

TypeBinary (bytes)String (chars)Typical DB Type
UUID1636UUID, CHAR(36), BINARY(16)
ULID1626CHAR(26), BINARY(16)
NanoID~1621VARCHAR(21+)
Snowflake8~19BIGINT
ObjectId1224ObjectId, CHAR(24)

Feature Matrix

FeatureUUIDv4UUIDv7ULIDNanoIDSnowflake
Time-sortable-YesYes-Yes
Extract timestamp-YesYes-Yes
URL-safe--YesYesYes
Fits in 64-bit----Yes
No coordinationYesYesYesYes-
Customizable---YesYes
RFC standardYesYes---
Widely supportedYesGrowingGrowingGrowingYes