diff options
author | heqnx <root@heqnx.com> | 2025-07-04 13:59:57 +0300 |
---|---|---|
committer | heqnx <root@heqnx.com> | 2025-07-04 13:59:57 +0300 |
commit | 121c7aaf53b0f34ddec77424fecbdac993f2fe45 (patch) | |
tree | 4730ffc33a226b302ef9e62b7f251d8e4628eda0 /main.go | |
parent | fed1bf7e23b4da9c0d5dfe1d29dd2ff5e2be72ff (diff) | |
download | go-cryptonym-121c7aaf53b0f34ddec77424fecbdac993f2fe45.tar.gz go-cryptonym-121c7aaf53b0f34ddec77424fecbdac993f2fe45.zip |
initial commit
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 331 |
1 files changed, 331 insertions, 0 deletions
@@ -0,0 +1,331 @@ +package main + +import ( + "flag" + "fmt" + "math/rand" + "strings" + "time" + "unicode" +) + +var ( + syllables = []string{ + "ka", "lo", "mi", "te", "sa", "ri", "zu", "ve", "po", "ni", + "fa", "go", "bi", "du", "ze", "wi", "la", "mo", "si", "ta", + + "chi", "so", "ki", "ma", "ha", "yu", "tsu", "ko", "na", "fu", + "mi", "ya", "to", "hi", "su", "no", "ra", "se", "ku", "me", + + "el", "ar", "is", "on", "vi", "lu", "ce", "ra", "di", "vo", + "ti", "re", "ca", "li", "pe", "co", "mu", "ne", "si", "la", + + "skal", "vorn", "dre", "thor", "sig", "fre", "bjorn", "ulf", "ragn", "skol", + "grim", "tor", "val", "hild", "sven", "lok", "frig", "od", "run", "skir", + + "bri", "cen", "lor", "ael", "wyn", "fion", "dea", "mor", "cai", "lyn", + "glen", "row", "sev", "bran", "cer", "dru", "fin", "gwen", "lir", "mae", + + "za", "nur", "sal", "jam", "far", "lay", "ami", "rah", "sah", "nad", + "mal", "yas", "zin", "bah", "qas", "hil", "ram", "sul", "zar", "mun", + + "vla", "mir", "sto", "dre", "bor", "slav", "rad", "mil", "ziv", "gor", + "dan", "luk", "pet", "nik", "sov", "yar", "zol", "kras", "vit", "bog", + + "nde", "kwe", "zuri", "oba", "chi", "tum", "san", "yem", "fol", "dji", + "bwe", "kud", "mal", "ngo", "sia", "tan", "waz", "yol", "zim", "kwa", + + "dev", "sri", "jai", "anu", "raj", "pri", "san", "vid", "kir", "ran", + "ash", "vik", "dip", "man", "sur", "tar", "neh", "par", "jit", "sam", + + "theo", "nyx", "eos", "zir", "phi", "rho", "kai", "zel", "ion", "pyr", + "hel", "tha", "cri", "lys", "dor", "xan", "nym", "pol", "ath", "zen", + + "moa", "lua", "kai", "nalu", "hina", "mana", "tane", "rua", "vai", "lea", + + "wald", "grim", "hart", "stein", "burg", "feld", "wolf", "brand", "helm", "sieg", + + "ay", "gul", "tur", "khan", "sel", "yur", "tem", "bar", "oz", "alp", + } + words = []string{ + "sky", "leaf", "stone", "cloud", "river", "moon", "wind", "tree", "hill", "dawn", + "mist", "vale", "ridge", "bloom", "shade", "wave", "pine", "oak", "fern", "lake", + "dune", "brook", "frost", "glen", "tide", "cove", "reef", "snow", "breeze", "field", + "sand", "peak", "wood", "stream", "bay", "crag", "pond", "marsh", "cliff", "mead", + "spruce", "cedar", "vine", "moss", "thorn", "birch", "ash", "elm", "heath", "gorge", + + "dream", "echo", "spark", "flow", "haze", "gleam", "pulse", "vibe", "dusk", "hope", + "calm", "glow", "whisper", "drift", "flicker", "muse", "soul", "void", "quest", "fate", + "bliss", "surge", "glee", "trust", "peace", "spirit", "charm", "vision", "awe", "grace", + "clarity", "essence", "radiance", "serenity", "mirth", "zest", "bloom", "luster", "shade", + "gleam", "sparkle", "wisp", "nexus", "vapor", "glee", "mood", "scent", "breeze", "tide", + + "key", "flame", "path", "crown", "forge", "veil", "spire", "gem", "lock", "chain", + "lamp", "coin", "blade", "ring", "scroll", "torch", "bell", "horn", "vase", "cloak", + "shield", "spear", "flag", "book", "gate", "mirror", "staff", "wand", "chest", "map", + "drum", "quill", "rope", "wheel", "hook", "lens", "knot", "pipe", "cup", "bowl", + "plate", "knife", "rod", "candle", "locket", "pendant", "banner", "beacon", "forge", "loom", + + "nova", "orbit", "luna", "comet", "star", "galaxy", "nebula", "cosmo", "pulse", "ray", + "quasar", "meteor", "sun", "void", "eclipse", "astro", "light", "dawn", "dusk", "sky", + "flare", "crater", "dust", "ring", "belt", "moon", "tide", "glint", "beam", "spark", + "cluster", "void", "halo", "arc", "zenith", "nadir", "sky", "luster", "gleam", "vapor", + "corona", "umbra", "penumbra", "aurora", "cosmos", "spire", "vortex", "nebula", "pulsar", "orbit", + + "nyx", "zephyr", "aura", "titan", "phoenix", "siren", "griffin", "hydra", "minos", "atlas", + "hera", "zeus", "odin", "thor", "loki", "freya", "cronos", "ares", "muse", "fury", + "apollo", "artemis", "prometheus", "helios", "selene", "pan", "echo", "nereus", "psyche", "eros", + "orion", "hermes", "hades", "persephone", "dionysus", "athena", "hector", "achilles", "triton", "nymph", + "centaur", "satyr", "medusa", "cerberus", "chimera", "pegasus", "icarus", "daedalus", "midgard", "valhalla", + + "joy", "hope", "fear", "love", "rage", "calm", "glee", "sorrow", "trust", "pride", + "bliss", "awe", "grief", "zeal", "peace", "lust", "wrath", "cheer", "dread", "gleam", + "mirth", "gloom", "fervor", "ease", "fury", "spark", "zest", "muse", "thrill", "calm", + "ardor", "glee", "woe", "rapture", "vibe", "pang", "blaze", "whisper", "pulse", "dream", + "delight", "sigh", "yearn", "mood", "spirit", "surge", "charm", "elation", "serenity", "vigor", + + "azure", "crimson", "emerald", "amber", "violet", "ruby", "sapphire", "onyx", "jade", "gold", + "silver", "ivory", "ebony", "coral", "topaz", "pearl", "garnet", "opal", "turquoise", "amethyst", + "bronze", "copper", "sienna", "indigo", "vermilion", "ochre", "saffron", "mauve", "lavender", "teal", + "maroon", "cerulean", "cobalt", "sepia", "magenta", "cyan", "olive", "taupe", "rose", "lilac", + "umber", "sable", "chartreuse", "vermilion", "puce", "fuchsia", "aqua", "bistre", "sage", "mint", + + "fire", "water", "earth", "air", "stone", "ice", "storm", "flame", "tide", "mist", + "wind", "soil", "sky", "snow", "ash", "clay", "rock", "wave", "dust", "fog", + "blaze", "stream", "breeze", "frost", "sand", "magma", "vapor", "spark", "glint", "surge", + "quartz", "ember", "gust", "silt", "rubble", "dew", "spray", "rift", "smoke", "foam", + "gale", "cinder", "ore", "salt", "soot", "gravel", "slag", "haze", "ridge", "crust", + } + modifiers = []string{ + "neo", "ix", "al", "en", "ora", "is", "yn", "io", "za", "qu", + "ex", "um", "an", "er", "os", "ad", "il", "or", "es", "ys", + "ax", "on", "et", "im", "us", "id", "ox", "em", "ar", "un", + "ol", "az", "ir", "ov", "ut", "av", "ez", "om", "in", "ep", + "as", "iz", "ed", "up", "at", "it", "ef", "ag", "am", "oc", + + "byte", "code", "link", "sys", "net", "tech", "data", "grid", "bit", "wave", + "hack", "node", "port", "chip", "flux", "core", "sync", "pulse", "lan", "web", + "byte", "scan", "loop", "disk", "ram", "mod", "algo", "hash", "ping", "boot", + "cache", "link", "wire", "bolt", "spark", "flow", "beam", "drive", "glitch", "frame", + "pixel", "voxel", "quantum", "circuit", "relay", "signal", "stream", "cloud", "cyber", "nano", + + "zen", "vox", "lux", "syn", "arc", "haze", "gleam", "flow", "dusk", "mist", + "void", "spark", "echo", "drift", "aura", "soul", "whisper", "flicker", "bliss", "calm", + "pulse", "vibe", "shade", "bloom", "surge", "glee", "trust", "peace", "spirit", "charm", + "vision", "awe", "grace", "clarity", "essence", "radiance", "serenity", "mirth", "zest", "luster", + "dream", "hope", "muse", "wisp", "vapor", "gleam", "sparkle", "mood", "scent", "breeze", + + "kai", "ren", "sol", "mir", "xu", "yul", "zin", "rah", "sah", "jam", + "far", "lay", "ami", "nad", "bah", "qas", "hil", "ram", "sul", "zar", + "tal", "nur", "jem", "sal", "yaz", "khal", "zara", "nuri", "sami", "hana", + "ravi", "sana", "tari", "zain", "lila", "maya", "raj", "sri", "dev", "jai", + "anu", "kir", "vid", "ash", "vik", "dip", "man", "sur", "tar", "neh", + + "cryo", "plex", "nova", "zeta", "omni", "cyon", "lith", "quark", "ion", "nexus", + "volt", "pulse", "beam", "holo", "grid", "flux", "core", "spire", "link", "wave", + "chrono", "synth", "neo", "arc", "vox", "lume", "zoid", "micron", "photon", "plasma", + "cyber", "nano", "omega", "sigma", "delta", "theta", "gamma", "epsilon", "lambda", "mu", + "rho", "tau", "phi", "psi", "chi", "iota", "kappa", "beta", "alpha", "omicron", + + "verse", "tale", "saga", "epic", "rune", "myth", "fable", "ode", "lyric", "prose", + "sonnet", "ballad", "poem", "stanza", "rhyme", "epos", "lay", "saga", "yarn", "lore", + "canticle", "elegy", "psalm", "hymn", "chant", "fable", "mythos", "legend", "parable", "story", + "novella", "epic", "ode", "verse", "rune", "tale", "saga", "lyric", "prose", "ballad", + "sonnet", "poem", "stanza", "rhyme", "epos", "lay", "yarn", "lore", "canticle", "elegy", + + "note", "chord", "tune", "beat", "rhythm", "mel", "song", "vibe", "harmony", "tempo", + "pitch", "scale", "key", "tone", "cadence", "lilt", "hum", "riff", "melody", "verse", + "chorus", "bridge", "hook", "strain", "bar", "meter", "pulse", "flow", "swing", "jazz", + "blues", "rock", "pop", "folk", "soul", "funk", "reggae", "samba", "tango", "waltz", + "sonata", "fugue", "prelude", "coda", "aria", "rondo", "symphony", "ballad", "chant", "hymn", + } + vowels = []string{ + "a", "e", "i", "o", "u", "ai", "ou", "ae", "ei", "oa", "au", "ie", + "ue", "oi", "ui", "ea", "eo", "io", "ua", "ay", "ao", "eu", "iu", "oy", + "ya", "ye", "yo", "yu", + } + consonants = []string{ + "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "r", "s", "t", + "v", "w", "y", "z", "sh", "ch", "th", "ph", "kr", "sl", "br", "tr", "kl", + "gr", "fl", "pr", "dr", "sk", "sm", "sn", "sp", "st", "sw", "bl", "cl", + "fr", "gl", "pl", "sc", "tw", "wh", "zh", "qu", + } +) + +func GenerateUsername(minLength, maxLength int, noNumbers, noCamelCase bool) string { + rand.Seed(time.Now().UnixNano() ^ int64(rand.Int())) + var username strings.Builder + + separators := []string{"-", "_"} + separator := separators[rand.Intn(len(separators))] + + strategy := rand.Intn(5) + switch strategy { + case 0: + numSyllables := rand.Intn(3) + 2 + for i := 0; i < numSyllables; i++ { + syllable := syllables[rand.Intn(len(syllables))] + if rand.Float32() < 0.4 { + syllable = strings.Title(syllable) + } + username.WriteString(syllable) + if i < numSyllables-1 && rand.Float32() < 0.2 { + username.WriteString(separator) + } + } + + case 1: + word := words[rand.Intn(len(words))] + if rand.Float32() < 0.5 { + word = strings.Title(word) + } + username.WriteString(word) + if rand.Float32() < 0.6 { + modifier := modifiers[rand.Intn(len(modifiers))] + if rand.Float32() < 0.5 { + modifier = strings.Title(modifier) + } + username.WriteString(modifier) + } else { + syllable := syllables[rand.Intn(len(syllables))] + if rand.Float32() < 0.5 { + syllable = strings.Title(syllable) + } + username.WriteString(syllable) + } + + case 2: + length := rand.Intn(4) + 3 + for i := 0; i < length; i++ { + if i%2 == 0 && rand.Float32() < 0.7 { + username.WriteString(consonants[rand.Intn(len(consonants))]) + } else { + username.WriteString(vowels[rand.Intn(len(vowels))]) + } + } + if rand.Float32() < 0.4 { + result := username.String() + if len(result) > 0 { + runes := []rune(result) + runes[0] = unicode.ToUpper(runes[0]) + username = strings.Builder{} + username.WriteString(string(runes)) + } + } + + case 3: + components := []string{ + syllables[rand.Intn(len(syllables))], + words[rand.Intn(len(words))], + modifiers[rand.Intn(len(modifiers))], + } + rand.Shuffle(len(components), func(i, j int) { + components[i], components[j] = components[j], components[i] + }) + numComponents := rand.Intn(2) + 2 + for i := 0; i < numComponents; i++ { + comp := components[i] + if rand.Float32() < 0.5 { + comp = strings.Title(comp) + } + username.WriteString(comp) + if i < numComponents-1 && rand.Float32() < 0.2 { + username.WriteString(separator) + } + } + + case 4: + length := rand.Intn(5) + 4 + pattern := rand.Intn(3) + for i := 0; i < length; i++ { + if pattern == 0 { + if i%2 == 0 { + username.WriteString(consonants[rand.Intn(len(consonants))]) + } else { + username.WriteString(vowels[rand.Intn(len(vowels))]) + } + } else if pattern == 1 { + if rand.Float32() < 0.6 { + username.WriteString(vowels[rand.Intn(len(vowels))]) + } else { + username.WriteString(consonants[rand.Intn(len(consonants))]) + } + } else { + if rand.Float32() < 0.6 { + username.WriteString(consonants[rand.Intn(len(consonants))]) + } else { + username.WriteString(vowels[rand.Intn(len(vowels))]) + } + } + } + if !noCamelCase && rand.Float32() < 0.3 { + result := username.String() + words := strings.Split(result, "") + for i := range words { + if rand.Float32() < 0.2 { + words[i] = strings.Title(words[i]) + } + } + username = strings.Builder{} + username.WriteString(strings.Join(words, "")) + } + } + + if !noNumbers && rand.Float32() < 0.05 { + num := rand.Intn(100) + username.WriteString(fmt.Sprintf("%02d", num)) + } + + if rand.Float32() < 0.05 { + result := username.String() + if strings.Contains(result, "a") { + result = strings.Replace(result, "a", "ae", 1) + username = strings.Builder{} + username.WriteString(result) + } + } + + result := username.String() + + if len(result) < minLength || len(result) > maxLength { + return GenerateUsername(minLength, maxLength, noNumbers, noCamelCase) + } + + lowerResult := strings.ToLower(result) + for _, word := range words { + if lowerResult == word { + return GenerateUsername(minLength, maxLength, noNumbers, noCamelCase) + } + } + + if rand.Float32() < 0.1 { + result = strings.Replace(result, "-", ".", 1) + result = strings.Replace(result, "_", ".", 1) + } + + return result +} + +func main() { + minLength := flag.Int("min-length", 8, "minimum username length") + maxLength := flag.Int("max-length", 12, "maximum username length") + noNumbers := flag.Bool("no-numbers", false, "disable appending numbers") + noCamelCase := flag.Bool("no-camelcase", false, "disable camelCase styling") + count := flag.Int("count", 10, "number of usernames to generate") + + flag.Parse() + + if *minLength > *maxLength { + fmt.Println("[err] min-length cannot be greater than max-length") + return + } + if *count <= 0 { + fmt.Println("[err] count must be positive") + return + } + + for i := 0; i < *count; i++ { + fmt.Println(GenerateUsername(*minLength, *maxLength, *noNumbers, *noCamelCase)) + } +} + |