13 func randomLine(f *os.File) (string, error) {
18 offset := rand.Int63n(fi.Size())
19 offset, err = f.Seek(offset, io.SeekStart)
24 br := bufio.NewReader(f)
26 b, err := br.ReadByte()
34 line, err := br.ReadString('\n')
35 if errors.Is(err, io.EOF) {
36 // the file ends without a newline - no problem
37 } else if err != nil {
41 line = strings.TrimSpace(line)
43 // empty line. we're either at the end or hit a blank line. try again
49 // RandomUsername generates a random username from the dictionary file at dictpath.
50 // The dictionary file should be a newline delimited text file, one word per line.
51 // On Unix systems, the file /usr/share/dic/words is a suitable file.
52 func RandomUsername(dictpath string) (string, error) {
53 f, err := os.Open(dictpath)
55 return "", fmt.Errorf("open dictionary: %w", err)
59 first, err := randomLine(f)
61 return "", fmt.Errorf("first random word: %w", err)
63 first = strings.ToLower(first)
64 second, err := randomLine(f)
66 return "", fmt.Errorf("second random word: %w", err)
68 second = strings.ToLower(second)
70 return fmt.Sprintf("%s_%s%02d", first, second, rand.Intn(99)), nil