From d58c81bdfd761299199cb643a78732937021b19e Mon Sep 17 00:00:00 2001 From: Amolith Date: Tue, 8 Oct 2024 14:13:18 -0600 Subject: [PATCH] Add friendly type --- main.go | 76 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index ea03296bf49146f7d679d785f5a404ad421d4674..fcc515a489b4330a0954d8904c05e755927bc784 100644 --- a/main.go +++ b/main.go @@ -14,14 +14,25 @@ import ( ) var ( - length = 20 - version = "" + length = 20 + version = "" + consonants = "bcdfghjklmnpqrstvwxyz" + vowels = "aeiou" + numbers = "0123456789" + newBase60Chars = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz" ) func main() { if len(os.Args) > 1 && os.Args[1] == "-h" { printHelp() os.Exit(0) + } else if len(os.Args) > 1 && os.Args[1] == "-t" { + switch os.Args[2] { + case "nb60": + fmt.Println(generate(length)) + case "friendly": + fmt.Println(generateFriendly()) + } } else if len(os.Args) > 3 { fmt.Print("Error: too many arguments...\n\n") printHelp() @@ -57,8 +68,6 @@ func main() { } func generate(length int) string { - const newBase60Chars = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz" - rng := rand.New(rand.NewSource(time.Now().UnixNano())) var sb strings.Builder @@ -71,14 +80,61 @@ func generate(length int) string { return sb.String() } +func generateFriendly() string { + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + + sets := make([]string, 3) + for i := 0; i < 3; i++ { + sets[i] = genFriendlySet(rng) + } + + result := strings.Join(sets, "-") + + letterPos := rng.Intn(len(result)) + // Generate a different position until a non-separator is found + for result[letterPos] == '-' { + letterPos = rng.Intn(len(result)) + } + existingLetter := result[letterPos] + var newLetter string + if strings.Contains(consonants, string(existingLetter)) { + newLetter = string(consonants[rng.Intn(len(consonants))]) + } else if strings.Contains(vowels, string(existingLetter)) { + newLetter = string(vowels[rng.Intn(len(vowels))]) + } + result = result[:letterPos] + newLetter + result[letterPos+1:] + + // Generate a different position until a non-separator and non-uppercase-letter + // is found + numberPos := rng.Intn(len(result)) + for result[numberPos] == '-' || result[numberPos] == result[letterPos] { + numberPos = rng.Intn(len(result)) + } + result = result[:numberPos] + string(numbers[rng.Intn(len(numbers))]) + result[numberPos+1:] + + return result +} + +func genFriendlySet(rng *rand.Rand) string { + set := make([]byte, 6) + set[0] = consonants[rng.Intn(len(consonants))] + set[1] = vowels[rng.Intn(len(vowels))] + set[2] = consonants[rng.Intn(len(consonants))] + set[3] = consonants[rng.Intn(len(consonants))] + set[4] = vowels[rng.Intn(len(vowels))] + set[5] = consonants[rng.Intn(len(consonants))] + return string(set) +} + func printHelp() { - fmt.Println(`Usage: eow [-h] + fmt.Println(`Usage: eow [-h|-t] -h prints this help message -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.`) +-t prints a single 20-character NewBase60 (nb60) or friendly (friendly) + password. + +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.`) }