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:
- Auto-detects ID types - No need to specify the format when inspecting or converting
- Provides rich metadata - Extract timestamps, version info, and other embedded data
- Supports modern formats - UUIDv7, ULID, and other time-sortable IDs
- Integrates with your workflow - JSON output, stdin support, and Unix-friendly design
Supported ID Types
| Type | Sortable | Timestamp | Bits | Description |
|---|---|---|---|---|
| UUIDv1 | No | Yes | 128 | Timestamp + MAC address |
| UUIDv4 | No | No | 128 | Random |
| UUIDv6 | Yes | Yes | 128 | Reordered timestamp |
| UUIDv7 | Yes | Yes | 128 | Unix timestamp + random |
| ULID | Yes | Yes | 128 | Crockford Base32, lexicographically sortable |
| NanoID | No | No | ~126 | Compact URL-friendly ID |
| Snowflake | Yes | Yes | 64 | Twitter/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:
| Command | Alias | Description |
|---|---|---|
| gen | g | Generate new IDs |
| inspect | i | Analyze and decode IDs |
| convert | c | Convert between formats |
| validate | v | Check if input is valid |
| compare | - | Compare two IDs |
| info | - | Show ID type information |
Global Options
These options work with all commands:
| Option | Description |
|---|---|
-j, --json | Output in JSON format |
-p, --pretty | Pretty-print JSON output |
--no-color | Disable colored output |
-h, --help | Show help information |
-V, --version | Show 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:
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Error (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
| Argument | Description |
|---|---|
TYPE | ID type to generate (uuid, uuidv7, ulid, nanoid, snowflake, etc.) |
Options
| Option | Description |
|---|---|
-n, --count <N> | Number of IDs to generate (default: 1) |
-f, --format <FORMAT> | Output encoding format |
-o, --output <FILE> | Write output to file |
--no-newline | Don’t print trailing newline (single ID only) |
UUID Options
| Option | Description |
|---|---|
--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
| Option | Description |
|---|---|
--alphabet <CHARS> | Custom alphabet |
--length <N> | Custom length (default: 21) |
Snowflake Options
| Option | Description |
|---|---|
--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
| Option | Description |
|---|---|
--prefix <PREFIX> | Type prefix for TypeID |
Supported Types
| Type | Alias | Description |
|---|---|---|
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
| Argument | Description |
|---|---|
ID | ID(s) to inspect (reads from stdin if omitted) |
Options
| Option | Description |
|---|---|
-t, --type <TYPE> | Hint the ID type (skip auto-detection) |
-q, --quiet | Only show errors (for validation use) |
Output Fields
When inspecting an ID, idt displays:
| Field | Description |
|---|---|
| Type | Detected ID type (e.g., UUIDV7, ULID) |
| Canonical | The ID in its canonical format |
| Time (UTC) | Embedded timestamp in UTC (if available) |
| Local Time | Timestamp in local timezone with UTC offset (if available) |
| Version | UUID version number (for UUIDs) |
| Variant | UUID variant (for UUIDs) |
| Random | Number of random bits |
| Hex | Hexadecimal encoding |
| Base64 | Base64 encoding |
| Int | Integer 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
| Argument | Description |
|---|---|
ID | ID(s) to convert (reads from stdin if omitted) |
Options
| Option | Description |
|---|---|
-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, --uppercase | Uppercase output |
-L, --lowercase | Lowercase output |
Encoding Formats
| Format | Description | Example |
|---|---|---|
canonical | Original format | 550e8400-e29b-41d4-a716-446655440000 |
hex | Hexadecimal | 550e8400e29b41d4a716446655440000 |
base32 | Base32 (RFC 4648) | KUHIBAASSNE5JJYWIRDFKRAAAA |
base58 | Base58 | 6K8FVbLqP4V8nDqTJNXH6k |
base64 | Base64 | VQ6EAOKbQdSnFkRmVUQAAA== |
base64url | URL-safe Base64 | VQ6EAOKbQdSnFkRmVUQAAA |
bits | Binary string | 01010101000011101000... |
int | Integer | 113059749145936325402354257176981405696 |
bytes | Space-separated hex bytes | 55 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
| Argument | Description |
|---|---|
ID | ID(s) to validate (reads from stdin if omitted) |
Options
| Option | Description |
|---|---|
-t, --type <TYPE> | Expected ID type (any valid if omitted) |
-q, --quiet | No output, only exit code |
--strict | Strict validation (reject non-canonical forms) |
Exit Codes
| Code | Meaning |
|---|---|
| 0 | All IDs are valid |
| 1 | One 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
| Argument | Description |
|---|---|
ID1 | First ID to compare |
ID2 | Second ID to compare |
Options
| Option | Description |
|---|---|
-t, --type <TYPE> | ID type (auto-detect if omitted) |
Comparison Types
| Comparison | Description |
|---|---|
| Binary | Byte-by-byte comparison of raw ID data |
| Lexicographic | String comparison of canonical forms |
| Chronological | Time 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:
| Symbol | Meaning |
|---|---|
< | 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
| Argument | Description |
|---|---|
TYPE | ID 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 timestampS= 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
| Type | Bits | Sortable | Timestamp | Format |
|---|---|---|---|---|
| UUIDv1 | 128 | No | Yes | xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx |
| UUIDv4 | 128 | No | No | xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx |
| UUIDv6 | 128 | Yes | Yes | xxxxxxxx-xxxx-6xxx-xxxx-xxxxxxxxxxxx |
| UUIDv7 | 128 | Yes | Yes | xxxxxxxx-xxxx-7xxx-xxxx-xxxxxxxxxxxx |
| ULID | 128 | Yes | Yes | 01ARZ3NDEKTSV4RRFFQ69G5FAV |
| NanoID | ~126 | No | No | V1StGXR8_Z5jdHi6B-myT |
| Snowflake | 64 | Yes | Yes | 1234567890123456789 |
| KSUID | 160 | Yes | Yes | 0ujsswThIGTUYm2K8FjOOfXtY1K |
| ObjectId | 96 | Partial | Yes | 507f1f77bcf86cd799439011 |
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:
- UUID Family - UUIDv1, v3, v4, v5, v6, v7, nil, max
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:
- Other ID Types - KSUID, ObjectId, TypeID, XID, CUID, TSID
Generation Support
Not all ID types can be generated by idt. Here’s what’s supported:
| Type | Generate | Inspect | Convert | Validate |
|---|---|---|---|---|
| UUIDv1 | Yes | Yes | Yes | Yes |
| UUIDv4 | Yes | Yes | Yes | Yes |
| UUIDv6 | Yes | Yes | Yes | Yes |
| UUIDv7 | Yes | Yes | Yes | Yes |
| UUID-nil | Yes | Yes | Yes | Yes |
| UUID-max | Yes | Yes | Yes | Yes |
| ULID | Yes | Yes | Yes | Yes |
| NanoID | Yes | Yes | Yes | Yes |
| Snowflake | Yes | Yes | Yes | Yes |
Further Reading
- UUID Family - Detailed UUID version information
- ULID - ULID specification and usage
- NanoID - NanoID customization options
- Snowflake ID - Distributed ID generation
- Other ID Types - Additional formats
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:
Mindicates the version (1-8)Nindicates 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 Case | Recommended Version |
|---|---|
| General purpose, no special requirements | UUIDv4 |
| Need sortable IDs | UUIDv7 |
| Deterministic IDs from names | UUIDv5 |
| Legacy system compatibility | UUIDv1 |
| Sortable + v1 compatibility | UUIDv6 |
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
| Property | Value |
|---|---|
| Bits | 128 |
| Sortable | Yes |
| Timestamp | Yes (millisecond precision) |
| Format | Crockford Base32 |
| Length | 26 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
| Feature | ULID | UUIDv4 | UUIDv7 |
|---|---|---|---|
| Bits | 128 | 128 | 128 |
| Sortable | Yes | No | Yes |
| Timestamp | Yes | No | Yes |
| String length | 26 | 36 | 36 |
| Case-sensitive | No | No | No |
| URL-safe | Yes | With encoding | With 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
| Property | Value |
|---|---|
| Default bits | ~126 |
| Sortable | No |
| Timestamp | No |
| Default length | 21 characters |
| Customizable | Yes (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
| Feature | NanoID | UUID | ULID |
|---|---|---|---|
| Length | 21 | 36 | 26 |
| Sortable | No | No* | Yes |
| Timestamp | No | No* | Yes |
| URL-safe | Yes | No | Yes |
| Customizable | Yes | No | No |
*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
| Property | Value |
|---|---|
| Bits | 64 |
| Sortable | Yes |
| Timestamp | Yes (millisecond precision) |
| Format | Decimal integer |
| Coordination | Required (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
| Field | Bits | Description |
|---|---|---|
| Sign | 1 | Always 0 (positive) |
| Timestamp | 41 | Milliseconds since epoch |
| Datacenter ID | 5 | 0-31 |
| Worker/Machine ID | 5 | 0-31 |
| Sequence | 12 | 0-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
| System | Epoch | Milliseconds |
|---|---|---|
| Nov 4, 2010 | 1288834974657 | |
| Discord | Jan 1, 2015 | 1420070400000 |
| Jan 1, 2011 | 1293840000000 |
Comparison with Other IDs
| Feature | Snowflake | UUID | ULID |
|---|---|---|---|
| Bits | 64 | 128 | 128 |
| Sortable | Yes | No* | Yes |
| Timestamp | Yes | No* | Yes |
| Coordination | Required | No | No |
| Throughput | Very high | High | High |
*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:
| System | Timestamp | DC/Worker | Sequence |
|---|---|---|---|
| 41 | 10 (5+5) | 12 | |
| Discord | 42 | 10 (5+5) | 12 |
| 41 | 13 | 10 |
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.
| Property | Value |
|---|---|
| Bits | 160 |
| Sortable | Yes |
| Timestamp | Yes (second precision) |
| Format | Base62 |
| Length | 27 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.
| Property | Value |
|---|---|
| Bits | 96 |
| Sortable | Partial |
| Timestamp | Yes (second precision) |
| Format | Hexadecimal |
| Length | 24 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.
| Property | Value |
|---|---|
| Bits | 128 |
| Sortable | Yes |
| Timestamp | Yes |
| Format | Prefix + 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.
| Property | Value |
|---|---|
| Bits | 96 |
| Sortable | Yes |
| Timestamp | Yes (second precision) |
| Format | Base32 |
| Length | 20 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.
| Property | Value |
|---|---|
| Bits | ~128 |
| Sortable | Partial |
| Timestamp | Yes |
| Format | Custom Base36 |
Format
cjld2cjxh0000qzrmn831i7rn
|-----------------------|
25+ characters
Structure
cprefix- Timestamp
- Counter
- Client fingerprint
- Random block
Specification
https://github.com/paralleldrive/cuid
CUID2
Secure, collision-resistant identifier (CUID successor).
| Property | Value |
|---|---|
| Bits | Variable |
| Sortable | No |
| Timestamp | No |
| Format | Base36 |
| Default length | 24 characters |
Characteristics
- Cryptographically secure
- No timestamp (privacy-focused)
- Configurable length
Specification
https://github.com/paralleldrive/cuid2
TSID
Time-Sorted Unique Identifier.
| Property | Value |
|---|---|
| Bits | 64 |
| Sortable | Yes |
| Timestamp | Yes |
| Format | Base32 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
| Type | Bits | Sortable | Timestamp | Length |
|---|---|---|---|---|
| KSUID | 160 | Yes | Seconds | 27 |
| ObjectId | 96 | Partial | Seconds | 24 |
| TypeID | 128 | Yes | Millis | Variable |
| XID | 96 | Yes | Seconds | 20 |
| CUID | ~128 | Partial | Yes | 25+ |
| CUID2 | Variable | No | No | 24 |
| TSID | 64 | Yes | Millis | 13-17 |
Support Status
These ID types have varying levels of support in idt:
| Type | Generate | Inspect | Convert | Validate |
|---|---|---|---|---|
| KSUID | Planned | Partial | Partial | Yes |
| ObjectId | Planned | Partial | Partial | Yes |
| TypeID | Planned | Partial | Partial | Yes |
| XID | Planned | Partial | Partial | Yes |
| CUID | No | Partial | Partial | Yes |
| CUID2 | No | Partial | Partial | Yes |
| TSID | Planned | Partial | Partial | Yes |
“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
- Generating IDs - ID generation patterns
- Inspecting IDs - Analyzing and decoding IDs
- Converting Formats - Format transformation
- Shell Scripting - Integration with shell scripts
- JSON Output - Machine-readable output
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
| Format | Description | Example (128-bit UUID) |
|---|---|---|
canonical | Original/standard format | 550e8400-e29b-41d4-a716-446655440000 |
hex | Hexadecimal (lowercase) | 550e8400e29b41d4a716446655440000 |
base32 | RFC 4648 Base32 | KUHIBAASSNE5JJYWIRDFKRAAAA |
base58 | Bitcoin-style Base58 | 6K8FVbLqP4V8nDqTJNXH6k |
base64 | Standard Base64 | VQ6EAOKbQdSnFkRmVUQAAA== |
base64url | URL-safe Base64 | VQ6EAOKbQdSnFkRmVUQAAA |
bits | Binary string | 01010101000011101000... |
int | Integer representation | 113059749145936325402354257176981405696 |
bytes | Space-separated hex bytes | 55 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
| Format | Length (128-bit) | URL-Safe | Human-Readable |
|---|---|---|---|
| canonical | 36 | No | Good |
| hex | 32 | Yes | Fair |
| base32 | 26 | Yes | Fair |
| base58 | ~22 | Yes | Good |
| base64 | 24 | No | Fair |
| base64url | 22 | Yes | Fair |
| bits | 128 | Yes | Poor |
| int | ~39 | Yes | Poor |
| bytes | 47 | No | Good |
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 Case | Recommended Format |
|---|---|
| Database storage | hex or canonical |
| URLs and APIs | base64url or base58 |
| Display to users | canonical or base58 |
| Compact storage | base58 or base64url |
| Cross-system compatibility | hex |
| Debugging | bytes or bits |
ID Types Comparison
A comprehensive comparison of all ID types supported by idt.
Quick Reference
| Type | Bits | Sortable | Timestamp | Random Bits | String Length |
|---|---|---|---|---|---|
| UUIDv1 | 128 | No | Yes | ~14 | 36 |
| UUIDv3 | 128 | No | No | 0 | 36 |
| UUIDv4 | 128 | No | No | 122 | 36 |
| UUIDv5 | 128 | No | No | 0 | 36 |
| UUIDv6 | 128 | Yes | Yes | ~62 | 36 |
| UUIDv7 | 128 | Yes | Yes | 62 | 36 |
| ULID | 128 | Yes | Yes | 80 | 26 |
| NanoID | ~126 | No | No | ~126 | 21 |
| Snowflake | 64 | Yes | Yes | 0 | ~19 |
| KSUID | 160 | Yes | Yes | 128 | 27 |
| ObjectId | 96 | Partial | Yes | ~40 | 24 |
| XID | 96 | Yes | Yes | ~40 | 20 |
| TSID | 64 | Yes | Yes | ~22 | 13-17 |
Detailed Comparison
Timestamp Precision
| Type | Precision | Epoch |
|---|---|---|
| UUIDv1 | 100 nanoseconds | October 15, 1582 |
| UUIDv6 | 100 nanoseconds | October 15, 1582 |
| UUIDv7 | Milliseconds | Unix epoch (1970) |
| ULID | Milliseconds | Unix epoch (1970) |
| Snowflake | Milliseconds | Custom (e.g., 2010, 2015) |
| KSUID | Seconds | May 13, 2014 |
| ObjectId | Seconds | Unix epoch (1970) |
| XID | Seconds | Unix epoch (1970) |
| TSID | Milliseconds | Unix epoch (1970) |
Collision Resistance
| Type | Same Millisecond | Different Nodes | Notes |
|---|---|---|---|
| UUIDv4 | Excellent | Excellent | 122 random bits |
| UUIDv7 | Good | Excellent | 62 random bits + timestamp |
| ULID | Excellent | Excellent | Monotonic + 80 random bits |
| NanoID | Excellent | Excellent | ~126 random bits |
| Snowflake | Limited | Requires coordination | 4096/ms per worker |
Encoding
| Type | Encoding | Case Sensitive | Alphabet |
|---|---|---|---|
| UUID | Hexadecimal | No | 0-9, a-f |
| ULID | Crockford Base32 | No | 0-9, A-Z (excluding I, L, O, U) |
| NanoID | Custom (default URL-safe) | Yes | A-Z, a-z, 0-9, -, _ |
| Snowflake | Decimal | N/A | 0-9 |
| KSUID | Base62 | Yes | 0-9, A-Z, a-z |
| ObjectId | Hexadecimal | No | 0-9, a-f |
| XID | Base32 | No | 0-9, a-v |
Use Case Recommendations
Database Primary Keys
| Requirement | Recommended Type |
|---|---|
| UUID compatibility required | UUIDv7 |
| Compact storage | ULID or Snowflake |
| Time-sortable queries | UUIDv7, ULID, or Snowflake |
| Maximum randomness | UUIDv4 |
| 64-bit integer column | Snowflake or TSID |
Distributed Systems
| Requirement | Recommended Type |
|---|---|
| No coordination needed | UUIDv7, ULID, UUIDv4 |
| Very high throughput | Snowflake |
| Cross-datacenter | UUIDv7 or ULID |
| Compact wire format | Snowflake (64-bit) |
User-Facing IDs
| Requirement | Recommended Type |
|---|---|
| Short URL slugs | NanoID (custom length) |
| Readable codes | NanoID (custom alphabet) |
| Compact but sortable | ULID |
| Standard format | UUID (canonical) |
Security-Sensitive
| Requirement | Recommended Type |
|---|---|
| Non-sequential | UUIDv4 or NanoID |
| Hide creation time | UUIDv4 or NanoID |
| Cryptographic randomness | UUIDv4 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
| Type | Binary (bytes) | String (chars) | Typical DB Type |
|---|---|---|---|
| UUID | 16 | 36 | UUID, CHAR(36), BINARY(16) |
| ULID | 16 | 26 | CHAR(26), BINARY(16) |
| NanoID | ~16 | 21 | VARCHAR(21+) |
| Snowflake | 8 | ~19 | BIGINT |
| ObjectId | 12 | 24 | ObjectId, CHAR(24) |
Feature Matrix
| Feature | UUIDv4 | UUIDv7 | ULID | NanoID | Snowflake |
|---|---|---|---|---|---|
| Time-sortable | - | Yes | Yes | - | Yes |
| Extract timestamp | - | Yes | Yes | - | Yes |
| URL-safe | - | - | Yes | Yes | Yes |
| Fits in 64-bit | - | - | - | - | Yes |
| No coordination | Yes | Yes | Yes | Yes | - |
| Customizable | - | - | - | Yes | Yes |
| RFC standard | Yes | Yes | - | - | - |
| Widely supported | Yes | Growing | Growing | Growing | Yes |
Specification Links
| Type | Specification |
|---|---|
| UUID (v1-v5) | RFC 4122 |
| UUID (v6-v8) | RFC 9562 |
| ULID | github.com/ulid/spec |
| NanoID | github.com/ai/nanoid |
| Snowflake | Wikipedia |
| KSUID | github.com/segmentio/ksuid |
| ObjectId | MongoDB Docs |
| XID | github.com/rs/xid |
| TypeID | github.com/jetify-com/typeid |