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 a87210a1 2022-04-14 o // /usr/share/dict/words contains derogatory words
50 a87210a1 2022-04-14 o // which we don't think should be used in public usernames.
51 a87210a1 2022-04-14 o func derogatory(s string) bool {
52 a87210a1 2022-04-14 o if s == "bitch" {
55 a87210a1 2022-04-14 o if strings.HasPrefix(s, "nigger") {
61 861fc513 2022-04-12 o // RandomUsername generates a random username from the dictionary file at dictpath.
62 861fc513 2022-04-12 o // The dictionary file should be a newline delimited text file, one word per line.
63 861fc513 2022-04-12 o // On Unix systems, the file /usr/share/dic/words is a suitable file.
64 8d82f4f7 2022-04-12 o func RandomUsername(dictpath string) (string, error) {
65 5e70998a 2022-04-12 o f, err := os.Open(dictpath)
66 5e70998a 2022-04-12 o if err != nil {
67 5e70998a 2022-04-12 o return "", fmt.Errorf("open dictionary: %w", err)
69 5e70998a 2022-04-12 o defer f.Close()
71 a87210a1 2022-04-14 o var first, second string
73 a87210a1 2022-04-14 o first, err = randomLine(f)
74 a87210a1 2022-04-14 o if err != nil {
75 a87210a1 2022-04-14 o return "", fmt.Errorf("first random word: %w", err)
77 a87210a1 2022-04-14 o first = strings.ToLower(first)
78 a87210a1 2022-04-14 o if !derogatory(first) {
83 a87210a1 2022-04-14 o second, err = randomLine(f)
84 a87210a1 2022-04-14 o if err != nil {
85 a87210a1 2022-04-14 o return "", fmt.Errorf("second random word: %w", err)
87 a87210a1 2022-04-14 o second = strings.ToLower(second)
88 a87210a1 2022-04-14 o if !derogatory(second) {
92 5e70998a 2022-04-12 o return fmt.Sprintf("%s_%s%02d", first, second, rand.Intn(99)), nil