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