mirror of
https://github.com/wneessen/apg-go.git
synced 2024-11-21 21:30:51 +01:00
#53 Add coinflip algorithm and improve error messages
Introduced a new password generation algorithm, called 'coinflip', which simply returns "Heads" or "Tails". Associated CLI flag has been added as well. Also, improved error messages during password generation. This addition provides a simpler algorithm option and clearer user feedback during errors.
This commit is contained in:
parent
8d42651e58
commit
2822f73f56
3 changed files with 42 additions and 4 deletions
5
algo.go
5
algo.go
|
@ -11,6 +11,9 @@ const (
|
|||
// AlgoRandom represents the algorithm for purely random passwords according
|
||||
// to the provided password modes/flags
|
||||
AlgoRandom
|
||||
// AlgoCoinFlip represents a very simple coinflip algorithm returning "heads"
|
||||
// or "tails"
|
||||
AlgoCoinFlip
|
||||
// AlgoUnsupported represents an unsupported algorithm
|
||||
AlgoUnsupported
|
||||
)
|
||||
|
@ -23,6 +26,8 @@ func IntToAlgo(a int) Algorithm {
|
|||
return AlgoPronouncable
|
||||
case 1:
|
||||
return AlgoRandom
|
||||
case 2:
|
||||
return AlgoCoinFlip
|
||||
default:
|
||||
return AlgoUnsupported
|
||||
}
|
||||
|
|
|
@ -15,8 +15,10 @@ func main() {
|
|||
|
||||
// Configure and parse the CLI flags
|
||||
// See usage() for flag details
|
||||
var al int
|
||||
var ms string
|
||||
var co, hr, lc, nu, sp, uc bool
|
||||
flag.IntVar(&al, "a", 1, "")
|
||||
flag.BoolVar(&lc, "L", false, "")
|
||||
flag.Int64Var(&c.MinLowerCase, "mL", c.MinLowerCase, "")
|
||||
flag.BoolVar(&uc, "U", false, "")
|
||||
|
@ -62,14 +64,22 @@ func main() {
|
|||
c.Mode = apg.ModesFromFlags(ms)
|
||||
}
|
||||
|
||||
// Check if algorithm is supported
|
||||
c.Algorithm = apg.IntToAlgo(al)
|
||||
if c.Algorithm == apg.AlgoUnsupported {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "unsupported algorithm value: %d\n", al)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Generate the password based on the given flags
|
||||
g := apg.New(c)
|
||||
for i := int64(0); i < c.NumberPass; i++ {
|
||||
pl, err := g.GetPasswordLength()
|
||||
p, err := g.Generate()
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "Error during password generation: %s\n", err)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "failed to generate password: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("PW length: %d\n", pl)
|
||||
fmt.Println(p)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +98,7 @@ Flags:
|
|||
-a ALGORITH Choose the password generation algorithm (Default: 1)
|
||||
- 0: pronounceable password generation (koremutake syllables)
|
||||
- 1: random password generation according to password modes/flags
|
||||
- 2: coinflip (returns heads or tails)
|
||||
-m LENGTH Minimum length of the password to be generated (Default: 12)
|
||||
-x LENGTH Maximum length of the password to be generated (Default: 20)
|
||||
-f LENGTH Fixed length of the password to be generated (Ignores -m and -x)
|
||||
|
|
24
random.go
24
random.go
|
@ -27,6 +27,28 @@ var (
|
|||
ErrInvalidCharRange = errors.New("provided character range is not valid or empty")
|
||||
)
|
||||
|
||||
// Generate generates a password based on all the different config flags and returns
|
||||
// it as string type. If the generation fails, an error will be thrown
|
||||
func (g *Generator) Generate() (string, error) {
|
||||
// Coinflip mode
|
||||
if g.config.Algorithm == AlgoCoinFlip {
|
||||
switch g.CoinFlipBool() {
|
||||
case true:
|
||||
return "Heads", nil
|
||||
case false:
|
||||
return "Tails", nil
|
||||
}
|
||||
}
|
||||
|
||||
l, err := g.GetPasswordLength()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to calculate password length: %w", err)
|
||||
}
|
||||
_ = l
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// RandomBytes returns a byte slice of random bytes with length n that got generated by
|
||||
// the crypto/rand generator
|
||||
func (g *Generator) RandomBytes(n int64) ([]byte, error) {
|
||||
|
@ -121,7 +143,7 @@ func (g *Generator) GetPasswordLength() (int64, error) {
|
|||
diff := mal - mil + 1
|
||||
ra, err := g.RandNum(diff)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to calculate password length: %w", err)
|
||||
return 0, err
|
||||
}
|
||||
l := mil + ra
|
||||
if l <= 0 {
|
||||
|
|
Loading…
Reference in a new issue