Blob


1 package mailmux
3 import (
4 "bufio"
5 "errors"
6 "fmt"
7 "io"
8 "math/rand"
9 "os"
10 "strings"
11 )
13 func randomLine(f *os.File) (string, error) {
14 fi, err := f.Stat()
15 if err != nil {
16 return "", err
17 }
18 offset := rand.Int63n(fi.Size())
19 offset, err = f.Seek(offset, io.SeekStart)
20 if err != nil {
21 return "", err
22 }
24 br := bufio.NewReader(f)
25 for {
26 b, err := br.ReadByte()
27 if b == '\n' {
28 break
29 }
30 if err != nil {
31 return "", err
32 }
33 }
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 {
38 return "", err
39 }
41 line = strings.TrimSpace(line)
42 if line == "" {
43 // empty line. we're either at the end or hit a blank line. try again
44 return randomLine(f)
45 }
46 return line, nil
47 }
49 func randomUsername(dictpath string) (string, error) {
50 f, err := os.Open(dictpath)
51 if err != nil {
52 return "", fmt.Errorf("open dictionary: %w", err)
53 }
54 defer f.Close()
56 first, err := randomLine(f)
57 if err != nil {
58 return "", fmt.Errorf("first random word: %w", err)
59 }
60 first = strings.ToLower(first)
61 second, err := randomLine(f)
62 if err != nil {
63 return "", fmt.Errorf("second random word: %w", err)
64 }
65 second = strings.ToLower(second)
67 return fmt.Sprintf("%s_%s%02d", first, second, rand.Intn(99)), nil
68 }