mirror of
https://github.com/wneessen/apg-go.git
synced 2024-12-23 03:30:39 +01:00
#53 Refactor mode handling and bitmask functions
The naming and handling of mode bitmasks have been refactored for improved code readability and maintainability. The term "Mode" was replaced with "ModeMask" for clarity and all associated functions were renamed accordingly (e.g., "SetMode" to "MaskSetMode"). These changes provide better insight into the function of the code and increase understandability for future development efforts. The command-line utility now also supports specifying modes via the "-M" flag.
This commit is contained in:
parent
ac97b94ec9
commit
b31219046a
4 changed files with 88 additions and 21 deletions
|
@ -4,6 +4,7 @@ package main
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/wneessen/apg-go"
|
||||
|
@ -13,12 +14,20 @@ func main() {
|
|||
c := apg.NewConfig()
|
||||
|
||||
// Configure and parse the CLI flags
|
||||
var ms string
|
||||
flag.Int64Var(&c.MinLength, "m", c.MinLength, "")
|
||||
flag.Int64Var(&c.MaxLength, "x", c.MaxLength, "")
|
||||
flag.StringVar(&ms, "M", "", "")
|
||||
flag.Int64Var(&c.NumberPass, "n", c.NumberPass, "")
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
if ms != "" {
|
||||
c.Modes = apg.ModesFromFlags(ms)
|
||||
}
|
||||
for _, m := range []apg.Mode{apg.ModeHumanReadable, apg.ModeLowerCase, apg.ModeNumber, apg.ModeSpecial, apg.ModeUpperCase} {
|
||||
fmt.Printf("%s: %t\n", m, apg.MaskHasMode(c.Modes, m))
|
||||
}
|
||||
/*
|
||||
g := apg.New(c)
|
||||
rb, err := g.RandomBytes(c.MinLength)
|
||||
|
|
|
@ -18,6 +18,8 @@ type Config struct {
|
|||
MaxLength int64
|
||||
// MinLength sets the minimum length for a generated password
|
||||
MinLength int64
|
||||
// Modes holds the different character modes for the Random algorithm
|
||||
Modes ModeMask
|
||||
// NumberPass sets the number of passwords that are generated
|
||||
// and returned by the generator
|
||||
NumberPass int64
|
||||
|
|
72
mode.go
72
mode.go
|
@ -1,8 +1,13 @@
|
|||
package apg
|
||||
|
||||
import "strings"
|
||||
|
||||
// Mode represents a mode of characters
|
||||
type Mode uint8
|
||||
|
||||
// ModeMask represents a bitmask of character modes
|
||||
type ModeMask uint8
|
||||
|
||||
const (
|
||||
// ModeNumber sets the bitmask to include numbers in the generated passwords
|
||||
ModeNumber = 1 << iota
|
||||
|
@ -38,14 +43,65 @@ const (
|
|||
CharRangeSpecialHuman = `#%*+-:;=`
|
||||
)
|
||||
|
||||
// SetMode sets a specific Mode to a given Mode bitmask
|
||||
func SetMode(b, m Mode) Mode { return b | m }
|
||||
// MaskSetMode sets a specific Mode to a given Mode bitmask
|
||||
func MaskSetMode(ma ModeMask, mo Mode) ModeMask { return ModeMask(uint8(ma) | uint8(mo)) }
|
||||
|
||||
// ClearMode clears a specific Mode from a given Mode bitmask
|
||||
func ClearMode(b, m Mode) Mode { return b &^ m }
|
||||
// MaskClearMode clears a specific Mode from a given Mode bitmask
|
||||
func MaskClearMode(ma ModeMask, mo Mode) ModeMask { return ModeMask(uint8(ma) &^ uint8(mo)) }
|
||||
|
||||
// ToggleMode toggles a specific Mode in a given Mode bitmask
|
||||
func ToggleMode(b, m Mode) Mode { return b ^ m }
|
||||
// MaskToggleMode toggles a specific Mode in a given Mode bitmask
|
||||
func MaskToggleMode(ma ModeMask, mo Mode) ModeMask { return ModeMask(uint8(ma) ^ uint8(mo)) }
|
||||
|
||||
// HasMode returns true if a given Mode bitmask holds a specific Mode
|
||||
func HasMode(b, m Mode) bool { return b&m != 0 }
|
||||
// MaskHasMode returns true if a given Mode bitmask holds a specific Mode
|
||||
func MaskHasMode(ma ModeMask, mo Mode) bool { return uint8(ma)&uint8(mo) != 0 }
|
||||
|
||||
func ModesFromFlags(ms string) ModeMask {
|
||||
var mm ModeMask
|
||||
for _, m := range strings.Split(ms, "") {
|
||||
switch m {
|
||||
case "C":
|
||||
mm = MaskSetMode(mm, ModeLowerCase|ModeNumber|ModeSpecial|ModeUpperCase)
|
||||
case "h":
|
||||
mm = MaskClearMode(mm, ModeHumanReadable)
|
||||
case "H":
|
||||
mm = MaskSetMode(mm, ModeHumanReadable)
|
||||
case "l":
|
||||
mm = MaskClearMode(mm, ModeLowerCase)
|
||||
case "L":
|
||||
mm = MaskSetMode(mm, ModeLowerCase)
|
||||
case "n":
|
||||
mm = MaskClearMode(mm, ModeNumber)
|
||||
case "N":
|
||||
mm = MaskSetMode(mm, ModeNumber)
|
||||
case "s":
|
||||
mm = MaskClearMode(mm, ModeSpecial)
|
||||
case "S":
|
||||
mm = MaskSetMode(mm, ModeSpecial)
|
||||
case "u":
|
||||
mm = MaskClearMode(mm, ModeUpperCase)
|
||||
case "U":
|
||||
mm = MaskSetMode(mm, ModeUpperCase)
|
||||
}
|
||||
}
|
||||
|
||||
return mm
|
||||
|
||||
}
|
||||
|
||||
// String satisfies the fmt.Stringer interface for the Mode type
|
||||
func (m Mode) String() string {
|
||||
switch m {
|
||||
case ModeHumanReadable:
|
||||
return "Human-readable"
|
||||
case ModeLowerCase:
|
||||
return "Lower-case"
|
||||
case ModeNumber:
|
||||
return "Number"
|
||||
case ModeSpecial:
|
||||
return "Special"
|
||||
case ModeUpperCase:
|
||||
return "Upper-case"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
|
26
mode_test.go
26
mode_test.go
|
@ -18,22 +18,22 @@ func TestSetClearHasToggleMode(t *testing.T) {
|
|||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var m Mode
|
||||
m = SetMode(m, tc.mode)
|
||||
if !HasMode(m, tc.mode) {
|
||||
t.Errorf("SetMode() failed, mode not found in bitmask")
|
||||
var m ModeMask
|
||||
m = MaskSetMode(m, tc.mode)
|
||||
if !MaskHasMode(m, tc.mode) {
|
||||
t.Errorf("MaskSetMode() failed, mode not found in bitmask")
|
||||
}
|
||||
m = ToggleMode(m, tc.mode)
|
||||
if HasMode(m, tc.mode) {
|
||||
t.Errorf("ToggleMode() failed, mode found in bitmask")
|
||||
m = MaskToggleMode(m, tc.mode)
|
||||
if MaskHasMode(m, tc.mode) {
|
||||
t.Errorf("MaskToggleMode() failed, mode found in bitmask")
|
||||
}
|
||||
m = ToggleMode(m, tc.mode)
|
||||
if !HasMode(m, tc.mode) {
|
||||
t.Errorf("ToggleMode() failed, mode not found in bitmask")
|
||||
m = MaskToggleMode(m, tc.mode)
|
||||
if !MaskHasMode(m, tc.mode) {
|
||||
t.Errorf("MaskToggleMode() failed, mode not found in bitmask")
|
||||
}
|
||||
m = ClearMode(m, tc.mode)
|
||||
if HasMode(m, tc.mode) {
|
||||
t.Errorf("ClearMode() failed, mode found in bitmask")
|
||||
m = MaskClearMode(m, tc.mode)
|
||||
if MaskHasMode(m, tc.mode) {
|
||||
t.Errorf("MaskClearMode() failed, mode found in bitmask")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue