deagon

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2025 License: Unlicense Imports: 5 Imported by: 0

README

Deagon — human readable random name generator

Note
This is a fork of lzap/deagon.
The maintained Go module is now published as: github.com/oakroots/deagon

Out of ideas for host names in your cluster? This little Go library and a CLI can help. It generates unique names based on frequently occurring given names and surnames from the 1990 US Census (public domain data):

  • 256 (8 bits) unique male given names
  • 256 (8 bits) unique female given names
  • 65,536 (16 bits) unique surnames
  • with over 120 gender-neutral given names

Given names were filtered to be 3–5 characters long, surnames 5–8 characters, therefore generated names are never longer than 14 characters (5+1+8).

This gives 33,554,432 (25 bits) total male and female name combinations. The built-in generator can either generate:

  • a pseudo-random unique succession (full-cycle linear feedback shift register), or
  • pseudo-random names via a time/random source.

Both a command-line utility and a Go library are available.

A similar project exists for Ruby: https://github.com/lzap/deacon


Changes in this fork

  • Module path changed to github.com/oakroots/deagon.
  • Switched random API to math/rand/v2 (no global seeding, no deprecated rand.Seed).
  • Fixed and clarified LFSR implementation (25-bit Fibonacci LFSR with proper feedback parity).
  • Modernized tests to property-based checks (fast, stable; optional long test with -short skip).
  • Code comments standardized in English; minor formatting utilities added.

Installation

go install github.com/oakroots/deagon@latest

Command-line tool

Generate a random name:

# generate
Elisabeth Sobeck

Lowercase with a dash:

# generate -d
ted-faron

Generate many:

# generate -n 10
Tyler Vilar
Ester Boniface
Melba Forkell
Irma Paolello
Sara Stika
Pedro Dockins
Molly Stogden
Bryan Mayhue
Logan Bushner
Shane Bondi

Generate a unique sequence: provide a starting seed between 1 and 2^25−2 (33,554,430).
Names are guaranteed unique across the sequence. The last output line prints the next seed to continue the sequence.

# generate -n 10 -s 130513
Jamie Abundis
Neil Abelardo
Ruben Abaunza
Teri Lebert
Tony Rizer
Vicky Sutler
Wanda Keaser
Wendy Doubek
Jim Burda
Emma Markee
18612351

The algorithm eliminates pairs with the same given name or the same surname between consecutive states. There are exactly 66,046 such states, so the total number of unique consecutive names is 33,488,385.


Go library

package main

import (
	"fmt"

	"github.com/oakroots/deagon"
)

func main() {
	// lowercase with a dash
	fmt.Println(deagon.RandomName(deagon.NewLowercaseDashFormatter()))

	// capitalized with space
	fmt.Println(deagon.RandomName(deagon.NewCapitalizedSpaceFormatter()))

	// generate from an integer (only low 25 bits are used)
	fmt.Println(deagon.Name(deagon.NewCapitalizedSpaceFormatter(), 130513))

	// generate pseudorandom unique sequence
	seed := 543235432
	nextSeed, name1 := deagon.PseudoRandomName(seed, true, deagon.NewCapitalizedSpaceFormatter())
	_, name2 := deagon.PseudoRandomName(nextSeed, true, deagon.NewCapitalizedSpaceFormatter())
	fmt.Println(name1, name2)
}

Pseudo-random generator

Generating names randomly does not guarantee uniqueness. There is, however, a technique called full cycle feedback register that ensures that two outputs never repeat for a given sequence of pseudorandom numbers until all numbers are exhausted.

How it works: you pick a random integer between 1 and 2^25-2 (33,554,430) and pass it to a function which returns a random name and the next number in the full cycle sequence. You need to store the number somewhere (e.g. a database) and the next time the function is called, use the stored number and repeat.

This guarantees that two same names are only returned after 33,554,432 calls, so there is plenty of names for everyone. This is guaranteed (and tested) to never return the same name so there is no need to do uniqueness checks.

It is based on a Fibonacci linear feedback shift register with polynomial (tap 0x10002A3):

x^25 + x^10 + x^8 + x^6 + x^2 + x + 1

There are exactly 66,046 states when given name or surname is the same as the previous state. Fun fact – due to nature of the pseudorandom generator, these names are only: Aaron, Wilma, Aaberg and Zywiec (the last and the first of firstnames and surnames). There is a boolean flag that will cause these names with the same firstname or surname to be skipped.


Contributing

Fork and send a Pull Request. Thanks!


Original work: © 2016 Lukas Zapletal
Forked and maintained under: © 2025 Oakroots

PUBLIC DOMAIN

Documentation

Index

Constants

View Source
const (
	// MASK is a 25-bit mask (2^25 - 1). Kept exported to avoid breaking callers.
	MASK = (1 << 25) - 1
)

Variables

This section is empty.

Functions

func GetNameWithType added in v1.2.0

func GetNameWithType(index int, formatter Formatter, t NameType) string

func Name

func Name(formatter Formatter, index int) string

Name returns a name from an index. Only low 25 bits from index are used.

func PseudoRandomName

func PseudoRandomName(seed int, eliminateCloseNames bool, formatter Formatter) (int, string)

PseudoRandomName returns a pseudorandom name for a given seed value and formats it via the provided formatter. It returns the next LFSR state (to be used for the next call) and the generated, formatted name.

The sequence is unique until it cycles after 2^25 - 2 states, excluding the all-zero state.

When eliminateCloseNames is true, successive calls never return the same firstname or surname. This skips 66,046 possible states and the loop becomes slightly shorter.

func RandomName

func RandomName(formatter Formatter) string

RandomName returns a random formatted name using the provided Formatter. It selects a random index from the full set of available entries.

Types

type CapitalizedSpaceFormatter

type CapitalizedSpaceFormatter struct {
	// contains filtered or unexported fields
}

CapitalizedSpaceFormatter joins first and last name in capitalized form with a space.

func NewCapitalizedSpaceFormatter

func NewCapitalizedSpaceFormatter() *CapitalizedSpaceFormatter

NewCapitalizedSpaceFormatter creates a new CapitalizedSpaceFormatter. Uses English capitalization rules.

func (*CapitalizedSpaceFormatter) Format

func (f *CapitalizedSpaceFormatter) Format(firstname, surname string) string

Format returns the names with each word capitalized.

type EmptyFormatter

type EmptyFormatter struct{}

EmptyFormatter always returns an empty string.

func NewEmptyFormatter

func NewEmptyFormatter() *EmptyFormatter

NewEmptyFormatter creates a new EmptyFormatter.

func (*EmptyFormatter) Format

func (*EmptyFormatter) Format(_, _ string) string

Format ignores inputs and returns an empty string.

type Formatter

type Formatter interface {
	Format(firstname, surname string) string
}

Formatter defines a common interface for formatting names.

type LowercaseDashFormatter

type LowercaseDashFormatter struct{}

LowercaseDashFormatter joins first and last name in lowercase with a dash.

func NewLowercaseDashFormatter

func NewLowercaseDashFormatter() *LowercaseDashFormatter

NewLowercaseDashFormatter creates a new LowercaseDashFormatter.

func (*LowercaseDashFormatter) Format

func (*LowercaseDashFormatter) Format(firstname, surname string) string

Format returns the names in lowercase separated by a dash.

type NameType added in v1.2.0

type NameType int
const (
	NameAuto NameType = iota
	NameMale
	NameFemale
	NameFantasy
)

type UppercaseSpaceFormatter

type UppercaseSpaceFormatter struct{}

UppercaseSpaceFormatter joins first and last name in uppercase with a space.

func NewUppercaseSpaceFormatter

func NewUppercaseSpaceFormatter() *UppercaseSpaceFormatter

NewUppercaseSpaceFormatter creates a new UppercaseSpaceFormatter.

func (*UppercaseSpaceFormatter) Format

func (*UppercaseSpaceFormatter) Format(firstname, surname string) string

Format returns the names in uppercase separated by a space.

Directories

Path Synopsis
cmd
deagon-generate command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL