Initial commit

Amolith created

Change summary

go.mod  |  3 ++
main.go | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+)

Detailed changes

go.mod 🔗

@@ -0,0 +1,3 @@
+module git.sr.ht/~amolith/ieo
+
+go 1.23.1

main.go 🔗

@@ -0,0 +1,80 @@
+package main
+
+import (
+	"fmt"
+	"math/rand"
+	"os"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var (
+	length  = 20
+	version = ""
+)
+
+func main() {
+	if len(os.Args) > 1 && os.Args[1] == "-h" {
+		printHelp()
+		os.Exit(0)
+	} else if len(os.Args) > 3 {
+		fmt.Print("Error: too many arguments...\n\n")
+		printHelp()
+		os.Exit(1)
+	} else if len(os.Args) == 2 {
+		// Convert the string argument to an int
+		length, err := strconv.Atoi(os.Args[1])
+		if err != nil {
+			fmt.Println("Error: length must be an integer")
+			os.Exit(1)
+		}
+		fmt.Println(generate(length))
+		os.Exit(0)
+	} else if len(os.Args) == 3 {
+		length, err := strconv.Atoi(os.Args[1])
+		if err != nil {
+			fmt.Println("Error: length must be an integer")
+			os.Exit(1)
+		}
+		count, err := strconv.Atoi(os.Args[2])
+		if err != nil {
+			fmt.Println("Error: count must be an integer")
+			os.Exit(1)
+		}
+		for i := 0; i < count; i++ {
+			fmt.Println(generate(length))
+		}
+		os.Exit(0)
+	} else if len(os.Args) == 1 {
+		fmt.Println(generate(length))
+		os.Exit(0)
+	}
+}
+
+func generate(length int) string {
+	const newBase60Chars = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz"
+
+	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
+
+	var sb strings.Builder
+	sb.Grow(length)
+
+	for i := 0; i < length; i++ {
+		sb.WriteByte(newBase60Chars[rng.Intn(len(newBase60Chars))])
+	}
+
+	return sb.String()
+}
+
+func printHelp() {
+	fmt.Println(`Usage: ieo <length> <count>
+
+Generates count passwords of length length.
+
+Arguments are positional, so length AND count
+may be omitted OR count may be omitted. If
+specifying count, length must also be
+specified. When ommitted, length defaults to
+20 and count defaults to 1.`)
+}