commit - /dev/null
commit + 1fdf07b79b193a5a1caf7d939f36b824a13086f4
blob - /dev/null
blob + 044b38889b0da1ab6bcf5d50dda1ccb7762c6dcc (mode 644)
--- /dev/null
+++ main.go
+package main
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "io"
+ "math/rand"
+ "os"
+ "strings"
+ "time"
+)
+
+func randomLine(f *os.File) (string, error) {
+ fi, err := f.Stat()
+ if err != nil {
+ return "", err
+ }
+ offset := rand.Int63n(fi.Size())
+ offset, err = f.Seek(offset, io.SeekStart)
+ if err != nil {
+ return "", err
+ }
+
+ br := bufio.NewReader(f)
+ for {
+ b, err := br.ReadByte()
+ if b == '\n' {
+ break
+ }
+ if err != nil {
+ return "", err
+ }
+ }
+ line, err := br.ReadString('\n')
+ if errors.Is(err, io.EOF) {
+ // the file ends without a newline - no problem
+ } else if err != nil {
+ return "", err
+ }
+
+ line = strings.TrimSpace(line)
+ if line == "" {
+ // empty line. we're either at the end or hit a blank line. try again
+ return randomLine(f)
+ }
+ return line, nil
+}
+
+func randomAddr(dictpath string, domain string) (string, error) {
+ f, err := os.Open(dictpath)
+ if err != nil {
+ return "", fmt.Errorf("open dictionary: %w", err)
+ }
+ defer f.Close()
+
+ first, err := randomLine(f)
+ if err != nil {
+ return "", fmt.Errorf("first random word: %w", err)
+ }
+ first = strings.ToLower(first)
+ second, err := randomLine(f)
+ if err != nil {
+ return "", fmt.Errorf("second random word: %w", err)
+ }
+ second = strings.ToLower(second)
+
+ return fmt.Sprintf("%s_%s%02d@%s", first, second, rand.Intn(99), domain), nil
+}
+
+func init() {
+ rand.Seed(time.Now().UnixNano())
+}
+
+const usage string = "usage: randomalias target ..."
+
+func main() {
+ if len(os.Args) < 2 {
+ fmt.Println(usage)
+ os.Exit(1)
+ }
+ targets := os.Args[1:]
+ address, err := randomAddr("/usr/share/dict/words", "mailmux.net")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ for _, targ := range targets {
+ fmt.Printf("%s: %s\n", address, targ)
+ }
+}