1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
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))
}
}
|