go-pwgen/cmd/pwgen/main.go

68 lines
2 KiB
Go

package main
import (
"code.icb4dc0.de/prskr/go-pwgen"
"flag"
"fmt"
"log"
"os"
"strings"
)
// although there might be terminals where it's less, let's be pessimistic
const tabWidth = 8
var (
length uint
count int
letters uint
lowercase uint
uppercase uint
digits uint
specials uint
specialsAlphabet string
)
func main() {
flags := flag.NewFlagSet("pwgen", flag.ExitOnError)
flags.IntVar(&count, "count", 20, "Number of passwords to generate")
flags.UintVar(&length, "length", 20, "Length of each password to generate")
flags.UintVar(&letters, "letters", 0, "Number of letters to include at least")
flags.UintVar(&lowercase, "lowercase", 3, "Number of lowercase characters to include at least")
flags.UintVar(&uppercase, "uppercase", 3, "Number of uppercase characters to include at least")
flags.UintVar(&digits, "digits", 3, "Number of digits to include at least")
flags.UintVar(&specials, "specials", 0, "Number of special characters to include at least")
flags.StringVar(&specialsAlphabet, "specials-alphabet", pwgen.DefaultSpecialsAlphabet, "Special characters to include as special characters")
if err := flags.Parse(os.Args[1:]); err != nil {
log.Fatalf("Failed to parse arguments: %v", err)
}
terminalWidth := getWidth()
passwordsPerRow := int(terminalWidth / (length + tabWidth))
builder := strings.Builder{}
for i := 0; i < count; i += passwordsPerRow {
for j := 0; j < passwordsPerRow && i+j < count; j++ {
pw, err := pwgen.Generate(
pwgen.WithLength(length),
pwgen.WithLetters(letters),
pwgen.WithLowercase(lowercase),
pwgen.WithUppercase(uppercase),
pwgen.WithDigits(digits),
pwgen.WithSpecials(specials),
pwgen.WithSpecialsAlphabet(specialsAlphabet),
)
if err != nil {
log.Fatalf("Error occurred generating password: %v", err)
}
builder.WriteString(pw)
builder.WriteRune('\t')
}
fmt.Println(strings.TrimSuffix(builder.String(), "\t"))
builder.Reset()
}
}