MemorableIds

A flexible Elixir library for generating human-readable, memorable identifiers. Uses combinations of adjectives, nouns, verbs, adverbs, and prepositions with optional numeric/custom suffixes.

TypeScript version of this library: memorable-ids

Features

Installation

Add memorable_ids to your list of dependencies in mix.exs:

def deps do
  [
    {:memorable_ids, "~> 0.1.0"}
  ]
end

Quick Start

# Basic usage - 2 components
MemorableIds.generate() # "cute-rabbit"

# More components for uniqueness
MemorableIds.generate(%{components: 3}) # "large-fox-swim"

# Add numeric suffix for extra capacity
suffix_generators = MemorableIds.suffix_generators()
MemorableIds.generate(%{
  components: 2, 
  suffix: suffix_generators.number
}) # "quick-mouse-042"

# Custom separator
MemorableIds.generate(%{
  components: 2, 
  separator: "_"
}) # "warm_duck"

API Reference

generate(options \\ %{})

Generate a memorable ID with customizable options.

Parameters:

Returns:string - Generated memorable ID

Examples:

# Different component counts
MemorableIds.generate(%{components: 1}) # "bright"
MemorableIds.generate(%{components: 2}) # "cute-rabbit" 
MemorableIds.generate(%{components: 3}) # "large-fox-swim"
MemorableIds.generate(%{components: 4}) # "happy-owl-dance-quietly"
MemorableIds.generate(%{components: 5}) # "clever-fox-run-quickly-through"

# With suffixes
suffix_generators = MemorableIds.suffix_generators()
MemorableIds.generate(%{
  components: 2, 
  suffix: suffix_generators.number
}) # "safe-rabbit-042"

MemorableIds.generate(%{
  components: 2, 
  suffix: suffix_generators.hex
}) # "bright-owl-a7"

# Custom separators
MemorableIds.generate(%{separator: "_"}) # "warm_duck"
MemorableIds.generate(%{separator: "."}) # "cute.rabbit"

parse(id, separator \\ "-")

Parse a memorable ID back to its components.

Parameters:

Returns:map - Map with components list and suffix string

Examples:

MemorableIds.parse("cute-rabbit-042")
# %{components: ["cute", "rabbit"], suffix: "042"}

MemorableIds.parse("large-fox-swim")
# %{components: ["large", "fox", "swim"], suffix: nil}

MemorableIds.parse("warm_duck_123", "_")
# %{components: ["warm", "duck"], suffix: "123"}

Suffix Generators

Pre-built suffix generators for common use cases:

suffix_generators = MemorableIds.suffix_generators()

# 3-digit number (000-999) - adds 1,000x multiplier
suffix_generators.number.() # "042"

# 4-digit number (0000-9999) - adds 10,000x multiplier  
suffix_generators.number4.() # "1337"

# 2-digit hex (00-ff) - adds 256x multiplier
suffix_generators.hex.() # "a7"

# Timestamp (last 4 digits) - time-based
suffix_generators.timestamp.() # "8429"

# Single letter (a-z) - adds 26x multiplier
suffix_generators.letter.() # "k"

Analysis Functions

Plan capacity and understand collision probabilities:

# Calculate total possible combinations
MemorableIds.calculate_combinations(2) # 5,304 (2 components)
MemorableIds.calculate_combinations(2, 1000) # 5,304,000 (2 components + 3-digit suffix)
MemorableIds.calculate_combinations(3) # 212,160 (3 components)

# Calculate collision probability (Birthday Paradox)
MemorableIds.calculate_collision_probability(5304, 100) # 0.0093 (0.93% chance)

# Get comprehensive analysis
MemorableIds.get_collision_analysis(2)
# %{
#   total_combinations: 5304,
#   scenarios: [
#     %{ids: 50, probability: 0.0023, percentage: "0.23%"},
#     %{ids: 100, probability: 0.0093, percentage: "0.93%"},
#     %{ids: 200, probability: 0.037, percentage: "3.7%"},
#     %{ids: 500, probability: 0.218, percentage: "21.8%"}
#   ]
# }

Capacity & Collision Analysis

Total Combinations by Component Count

Components Total IDs Example
1 78 bright
2 5,304 cute-rabbit
3 212,160 large-fox-swim
4 5,728,320 happy-owl-dance-quietly
5 148,936,320 clever-fox-run-quickly-through

Suffix Multipliers

Suffix Type Multiplier Example
3-digit number ×1,000 cute-rabbit-042
4-digit number ×10,000 cute-rabbit-1337
2-digit hex ×256 cute-rabbit-a7
Single letter ×26 cute-rabbit-k

Collision Probability Examples

For 2 components (5,304 total combinations):

For 3 components (212,160 total combinations):

For 2 components + 3-digit suffix (5,304,000 total combinations):

Configuration Recommendations

Choose the right configuration based on your expected ID volume:

Use Case Recommendation Capacity Example
Small apps (<1K IDs) 2 components 5,304 cute-rabbit
Medium apps (1K-50K IDs) 3 components 212,160 large-fox-swim
Large apps (50K-500K IDs) 2-3 components + suffix 5M+ cute-rabbit-042
Enterprise (500K+ IDs) 4+ components + suffix 50M+ happy-owl-dance-042

Advanced Usage

Custom Suffix Generators

Create your own suffix logic:

# Custom timestamp suffix
timestamp_suffix = fn ->
  DateTime.utc_now()
  |> DateTime.to_unix(:millisecond)
  |> Integer.to_string()
  |> String.slice(-6..-1) # Last 6 digits
end

# Custom random string
random_string = fn ->
  :crypto.strong_rand_bytes(3)
  |> Base.encode32(case: :lower, padding: false)
  |> String.slice(0..2) # 3 random chars
end

# Use custom suffix
MemorableIds.generate(%{
  components: 2, 
  suffix: timestamp_suffix
}) # "cute-rabbit-123456"

Dictionary Access

Access the underlying word collections:

alias MemorableIds.Dictionary

IO.puts length(Dictionary.adjectives()) # 78
IO.puts length(Dictionary.nouns()) # 68
IO.puts length(Dictionary.verbs()) # 40
IO.puts length(Dictionary.adverbs()) # 27
IO.puts length(Dictionary.prepositions()) # 26

# Access individual words
IO.puts hd(Dictionary.adjectives()) # "cute"
IO.puts hd(Dictionary.nouns()) # "rabbit"

# Get statistics
stats = Dictionary.stats()
IO.inspect stats
# %{adjectives: 78, nouns: 68, verbs: 40, adverbs: 27, prepositions: 26}

Error Handling

try do
  MemorableIds.generate(%{components: 6}) # Invalid: max is 5
rescue
  ArgumentError -> IO.puts "Components must be between 1 and 5"
end

Performance Considerations

Generation Speed

Randomness Quality

Security Notes

âš ī¸ Important Security Information:

Development

Running Tests

# Run all tests
mix test

# Run with coverage
mix test --cover

# Run specific test file
mix test test/memorable_ids_test.exs

# Run doctests only
mix test --only doctest

Building Documentation

# Generate documentation
mix docs

# View documentation
open doc/index.html

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Development Setup

# Clone repository
git clone <repository-url>
cd memorable_ids

# Install dependencies
mix deps.get

# Run tests
mix test

# Check formatting
mix format --check-formatted

# Run static analysis
mix credo

Adding Custom Vocabulary

  1. Extend existing lists in lib/dictionary.ex
  2. Ensure words are URL-safe and human-readable
  3. Avoid duplicates to maintain combination count accuracy
  4. Update tests and documentation
  5. Run mix test to verify changes

Documentation

Documentation can be generated with ExDoc and published on HexDocs.

Once published, the docs can be found at https://hexdocs.pm/memorable_ids.

License

This project is open-sourced software licensed under the MIT license.

Copyrights in this project are retained by their contributors. See the license file for more information.


đŸ¤Ģ Psst! If you like my work you can support me via [GitHub sponsors](https://github.com/sponsors/riipandi).