deagon

package module
v0.0.0-...-ebbec8e Latest Latest
Warning

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

Go to latest
Published: Nov 8, 2022 License: Unlicense Imports: 5 Imported by: 0

README

Deagon - human readable random name generator

Out of ideas for host names in your cluster? This little Go library and a CLI can help. 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 of male and female name combinations. Built-in generator can either generate pseudo random unique succession (full cycle linear feedback register) or generate pseudo random names with a time seed.

Both command line utility and Go library with random or unique pseudorandom sequence generators are available.

Similar project exists for Ruby too: https://github.com/lzap/deacon

Installation
# go install github.com/lzap/deagon@latest
Command line tool

To generate a random name, just use the CLI utility:

# generate
Elisabeth Sobeck

To generate output in lower case without space:

# generate -d
ted-faron

To generate arbitrary amount of random names:

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

To generate sequence of unique names, you must provide a starting seed number between 1 and 2^25-2 (33,554,430). The names are guaranteed to be unique. The last line contains the next seed value that must be passed in to continue in the unique 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 same given names or surnames, there is exactly 66046 of them, therefore the total number of unique names available is 33,488,385. This covers the fact that the pseudo-random generator is not perfect and there are parts of the period which generates names with the same givenname or surname multiple times. See below for details.

Go library

The library provides random generation:

package main

import (
	"fmt"
	"github.com/lzap/deagon"
	"math/rand"
	"time"
)

func main() {
	rand.Seed(time.Now().UnixNano())
	
	// generate lower case with dash
	fmt.Println(deagon.RandomName(deagon.NewLowercaseDashFormatter()))
	
	// generate 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 (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 a same name so there is no need to do uniqueness check.

If you want more details, it is based on Fibonacci linear feedback shift register with polynomial (tap 0x10002A3):

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

There is exactly 66046 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 she same firstname or surname to be skipped.

Contributing

Fork and send a Pull Request. Thanks!

Copyright (c) 2016 Lukas Zapletal

PUBLIC DOMAIN

Documentation

Index

Constants

View Source
const MASK int = 0x1ffffff

Variables

This section is empty.

Functions

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. Returns the next state which must be provided for the next call, and the generated name.

Sequence of names is guaranteed to be unique until it cycles after 2^25-2 calls.

When eliminateCloseNames is set, successive calls never return same firstname or surname. This eliminates 66046 possible values, so the loop is slightly shorter.

func RandomName

func RandomName(formatter Formatter) string

RandomName returns a random name and formats it with the provided formatter.

Types

type CapitalizedSpaceFormatter

type CapitalizedSpaceFormatter struct{}

func NewCapitalizedSpaceFormatter

func NewCapitalizedSpaceFormatter() *CapitalizedSpaceFormatter

func (*CapitalizedSpaceFormatter) Format

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

type EmptyFormatter

type EmptyFormatter struct{}

func NewEmptyFormatter

func NewEmptyFormatter() *EmptyFormatter

func (*EmptyFormatter) Format

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

type Formatter

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

type LowercaseDashFormatter

type LowercaseDashFormatter struct{}

func NewLowercaseDashFormatter

func NewLowercaseDashFormatter() *LowercaseDashFormatter

func (*LowercaseDashFormatter) Format

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

type UppercaseSpaceFormatter

type UppercaseSpaceFormatter struct{}

func NewUppercaseSpaceFormatter

func NewUppercaseSpaceFormatter() *UppercaseSpaceFormatter

func (*UppercaseSpaceFormatter) Format

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

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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