package main import ( "bufio" "flag" "fmt" "io" "log" "math/rand" "os" "strconv" "strings" ) type random interface { Intn(n int) int } type generator struct { words int separator string titleWords bool addNumber bool dict []string } func (g *generator) loadWordsFile(fname string) error { fd, err := os.Open(fname) if err != nil { return err } defer fd.Close() return g.loadWords(fd) } func (g *generator) loadWords(r io.Reader) error { scanner := bufio.NewScanner(r) for scanner.Scan() { g.dict = append(g.dict, scanner.Text()) } return scanner.Err() } func (g generator) pick(rnd random) string { word := g.dict[rnd.Intn(len(g.dict))] if g.titleWords { return strings.Title(word) } return word } func (g generator) generate(rnd random) string { var v []string for i := 0; i < g.words; i++ { v = append(v, g.pick(rnd)) } if g.addNumber { v = append(v, strconv.Itoa(rnd.Intn(10))) } return strings.Join(v, g.separator) } func main() { var g generator flag.IntVar(&g.words, "words", 6, "min words") flag.StringVar(&g.separator, "separator", "-", "word separator") flag.BoolVar(&g.titleWords, "title", false, "make first letter uppercase") flag.BoolVar(&g.addNumber, "number", false, "append random number to the end (0 - 9)") flag.Parse() if err := g.loadWordsFile("data/wordlist.txt"); err != nil { log.Fatal(err) } fmt.Println(g.generate(rand.New(cryptoSource{}))) }