Improve code readability by refactoring variable names

Several variable names have been changed in 'random.go' to improve overall readability and code comprehension. Additionally, a typo was fixed and a new constant was introduced for the maximum value of Int32, to replace previously hard-coded values. The adjustments not only make the code more digestible, but also adhere to good coding practices.
This commit is contained in:
Winni Neessen 2024-03-07 23:22:28 +01:00
parent 8f8e439f56
commit e17da1a2c9
Signed by: wneessen
GPG key ID: 5F3AF39B820C119D
3 changed files with 92 additions and 82 deletions

View file

@ -88,7 +88,6 @@ func ModesFromFlags(ms string) ModeMask {
} }
return mm return mm
} }
// String satisfies the fmt.Stringer interface for the Mode type // String satisfies the fmt.Stringer interface for the Mode type

View file

@ -45,30 +45,43 @@ func TestModesFromFlags(t *testing.T) {
ms string ms string
mode []Mode mode []Mode
}{ }{
{"ModeComplex", "C", []Mode{ModeLowerCase, ModeNumeric, ModeSpecial, {"ModeComplex", "C", []Mode{
ModeUpperCase}}, ModeLowerCase, ModeNumeric, ModeSpecial,
ModeUpperCase,
}},
{"ModeHumanReadable", "H", []Mode{ModeHumanReadable}}, {"ModeHumanReadable", "H", []Mode{ModeHumanReadable}},
{"ModeLowerCase", "L", []Mode{ModeLowerCase}}, {"ModeLowerCase", "L", []Mode{ModeLowerCase}},
{"ModeNumeric", "N", []Mode{ModeNumeric}}, {"ModeNumeric", "N", []Mode{ModeNumeric}},
{"ModeUpperCase", "U", []Mode{ModeUpperCase}}, {"ModeUpperCase", "U", []Mode{ModeUpperCase}},
{"ModeSpecial", "S", []Mode{ModeSpecial}}, {"ModeSpecial", "S", []Mode{ModeSpecial}},
{"ModeLowerSpecialUpper", "LSUH", []Mode{ModeHumanReadable, {"ModeLowerSpecialUpper", "LSUH", []Mode{
ModeLowerCase, ModeSpecial, ModeUpperCase}}, ModeHumanReadable,
{"ModeComplexNoHumanReadable", "Ch", []Mode{ModeLowerCase, ModeLowerCase, ModeSpecial, ModeUpperCase,
ModeNumeric, ModeSpecial, ModeUpperCase}}, }},
{"ModeComplexNoLower", "Cl", []Mode{ModeNumeric, ModeSpecial, {"ModeComplexNoHumanReadable", "Ch", []Mode{
ModeUpperCase}}, ModeLowerCase,
{"ModeComplexNoNumber", "Cn", []Mode{ModeLowerCase, ModeSpecial, ModeNumeric, ModeSpecial, ModeUpperCase,
ModeUpperCase}}, }},
{"ModeComplexNoSpecial", "Cs", []Mode{ModeLowerCase, ModeNumeric, {"ModeComplexNoLower", "Cl", []Mode{
ModeUpperCase}}, ModeNumeric, ModeSpecial,
{"ModeComplexNoUpper", "Cu", []Mode{ModeLowerCase, ModeNumeric, ModeUpperCase,
ModeSpecial}}, }},
{"ModeComplexNoNumber", "Cn", []Mode{
ModeLowerCase, ModeSpecial,
ModeUpperCase,
}},
{"ModeComplexNoSpecial", "Cs", []Mode{
ModeLowerCase, ModeNumeric,
ModeUpperCase,
}},
{"ModeComplexNoUpper", "Cu", []Mode{
ModeLowerCase, ModeNumeric,
ModeSpecial,
}},
} }
for _, tc := range tt { for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var mm ModeMask mm := ModesFromFlags(tc.ms)
mm = ModesFromFlags(tc.ms)
for _, tm := range tc.mode { for _, tm := range tc.mode {
if !MaskHasMode(mm, tm) { if !MaskHasMode(mm, tm) {
t.Errorf("ModesFromFlags() failed, expected mode %q not found", t.Errorf("ModesFromFlags() failed, expected mode %q not found",

128
random.go
View file

@ -119,146 +119,146 @@ func (g *Generator) RandomStringFromCharRange(length int64, charRange string) (s
if len(charRange) < 1 { if len(charRange) < 1 {
return "", ErrInvalidCharRange return "", ErrInvalidCharRange
} }
rs := strings.Builder{} randString := strings.Builder{}
// As long as the length is smaller than the max. int32 value let's grow // As long as the length is smaller than the max. int32 value let's grow
// the string builder to the actual size, so we need less allocations // the string builder to the actual size, so we need less allocations
if length <= maxInt32 { if length <= maxInt32 {
rs.Grow(int(length)) randString.Grow(int(length))
} }
charRangeLength := len(charRange) charRangeLength := len(charRange)
rp := make([]byte, 8) randPool := make([]byte, 8)
_, err := rand.Read(rp) _, err := rand.Read(randPool)
if err != nil { if err != nil {
return rs.String(), err return randString.String(), err
} }
for i, c, r := length-1, binary.BigEndian.Uint64(rp), letterIdxMax; i >= 0; { for idx, char, rest := length-1, binary.BigEndian.Uint64(randPool), letterIdxMax; idx >= 0; {
if r == 0 { if rest == 0 {
_, err = rand.Read(rp) _, err = rand.Read(randPool)
if err != nil { if err != nil {
return rs.String(), err return randString.String(), err
} }
c, r = binary.BigEndian.Uint64(rp), letterIdxMax char, rest = binary.BigEndian.Uint64(randPool), letterIdxMax
} }
if idx := int(c & letterIdxMask); idx < charRangeLength { if i := int(char & letterIdxMask); i < charRangeLength {
rs.WriteByte(charRange[idx]) randString.WriteByte(charRange[i])
i-- idx--
} }
c >>= letterIdxBits char >>= letterIdxBits
r-- rest--
} }
return rs.String(), nil return randString.String(), nil
} }
// GetCharRangeFromConfig checks the Mode from the Config and returns a // GetCharRangeFromConfig checks the Mode from the Config and returns a
// list of all possible characters that are supported by these Mode // list of all possible characters that are supported by these Mode
func (g *Generator) GetCharRangeFromConfig() string { func (g *Generator) GetCharRangeFromConfig() string {
cr := strings.Builder{} charRange := strings.Builder{}
if MaskHasMode(g.config.Mode, ModeLowerCase) { if MaskHasMode(g.config.Mode, ModeLowerCase) {
switch MaskHasMode(g.config.Mode, ModeHumanReadable) { switch MaskHasMode(g.config.Mode, ModeHumanReadable) {
case true: case true:
cr.WriteString(CharRangeAlphaLowerHuman) charRange.WriteString(CharRangeAlphaLowerHuman)
default: default:
cr.WriteString(CharRangeAlphaLower) charRange.WriteString(CharRangeAlphaLower)
} }
} }
if MaskHasMode(g.config.Mode, ModeNumeric) { if MaskHasMode(g.config.Mode, ModeNumeric) {
switch MaskHasMode(g.config.Mode, ModeHumanReadable) { switch MaskHasMode(g.config.Mode, ModeHumanReadable) {
case true: case true:
cr.WriteString(CharRangeNumericHuman) charRange.WriteString(CharRangeNumericHuman)
default: default:
cr.WriteString(CharRangeNumeric) charRange.WriteString(CharRangeNumeric)
} }
} }
if MaskHasMode(g.config.Mode, ModeSpecial) { if MaskHasMode(g.config.Mode, ModeSpecial) {
switch MaskHasMode(g.config.Mode, ModeHumanReadable) { switch MaskHasMode(g.config.Mode, ModeHumanReadable) {
case true: case true:
cr.WriteString(CharRangeSpecialHuman) charRange.WriteString(CharRangeSpecialHuman)
default: default:
cr.WriteString(CharRangeSpecial) charRange.WriteString(CharRangeSpecial)
} }
} }
if MaskHasMode(g.config.Mode, ModeUpperCase) { if MaskHasMode(g.config.Mode, ModeUpperCase) {
switch MaskHasMode(g.config.Mode, ModeHumanReadable) { switch MaskHasMode(g.config.Mode, ModeHumanReadable) {
case true: case true:
cr.WriteString(CharRangeAlphaUpperHuman) charRange.WriteString(CharRangeAlphaUpperHuman)
default: default:
cr.WriteString(CharRangeAlphaUpper) charRange.WriteString(CharRangeAlphaUpper)
} }
} }
return cr.String() return charRange.String()
} }
func (g *Generator) checkMinimumRequirements(pw string) bool { func (g *Generator) checkMinimumRequirements(password string) bool {
ok := true ok := true
if g.config.MinLowerCase > 0 { if g.config.MinLowerCase > 0 {
var cr string var charRange string
switch MaskHasMode(g.config.Mode, ModeHumanReadable) { switch MaskHasMode(g.config.Mode, ModeHumanReadable) {
case true: case true:
cr = CharRangeAlphaLowerHuman charRange = CharRangeAlphaLowerHuman
default: default:
cr = CharRangeAlphaLower charRange = CharRangeAlphaLower
} }
m := 0 count := 0
for _, c := range cr { for _, char := range charRange {
m += strings.Count(pw, string(c)) count += strings.Count(password, string(char))
} }
if int64(m) < g.config.MinLowerCase { if int64(count) < g.config.MinLowerCase {
ok = false ok = false
} }
} }
if g.config.MinNumeric > 0 { if g.config.MinNumeric > 0 {
var cr string var charRange string
switch MaskHasMode(g.config.Mode, ModeHumanReadable) { switch MaskHasMode(g.config.Mode, ModeHumanReadable) {
case true: case true:
cr = CharRangeNumericHuman charRange = CharRangeNumericHuman
default: default:
cr = CharRangeNumeric charRange = CharRangeNumeric
} }
m := 0 count := 0
for _, c := range cr { for _, char := range charRange {
m += strings.Count(pw, string(c)) count += strings.Count(password, string(char))
} }
if int64(m) < g.config.MinNumeric { if int64(count) < g.config.MinNumeric {
ok = false ok = false
} }
} }
if g.config.MinSpecial > 0 { if g.config.MinSpecial > 0 {
var cr string var charRange string
switch MaskHasMode(g.config.Mode, ModeHumanReadable) { switch MaskHasMode(g.config.Mode, ModeHumanReadable) {
case true: case true:
cr = CharRangeSpecialHuman charRange = CharRangeSpecialHuman
default: default:
cr = CharRangeSpecial charRange = CharRangeSpecial
} }
m := 0 count := 0
for _, c := range cr { for _, char := range charRange {
m += strings.Count(pw, string(c)) count += strings.Count(password, string(char))
} }
if int64(m) < g.config.MinSpecial { if int64(count) < g.config.MinSpecial {
ok = false ok = false
} }
} }
if g.config.MinUpperCase > 0 { if g.config.MinUpperCase > 0 {
var cr string var charRange string
switch MaskHasMode(g.config.Mode, ModeHumanReadable) { switch MaskHasMode(g.config.Mode, ModeHumanReadable) {
case true: case true:
cr = CharRangeAlphaUpperHuman charRange = CharRangeAlphaUpperHuman
default: default:
cr = CharRangeAlphaUpper charRange = CharRangeAlphaUpper
} }
m := 0 count := 0
for _, c := range cr { for _, char := range charRange {
m += strings.Count(pw, string(c)) count += strings.Count(password, string(char))
} }
if int64(m) < g.config.MinUpperCase { if int64(count) < g.config.MinUpperCase {
ok = false ok = false
} }
} }
@ -268,31 +268,29 @@ func (g *Generator) checkMinimumRequirements(pw string) bool {
// generateCoinFlip is executed when Generate() is called with Algorithm set // generateCoinFlip is executed when Generate() is called with Algorithm set
// to AlgoCoinFlip // to AlgoCoinFlip
func (g *Generator) generateCoinFlip() (string, error) { func (g *Generator) generateCoinFlip() (string, error) {
switch g.CoinFlipBool() { if g.CoinFlipBool() {
case true:
return "Heads", nil return "Heads", nil
default:
return "Tails", nil
} }
return "Tails", nil
} }
// generateRandom is executed when Generate() is called with Algorithm set // generateRandom is executed when Generate() is called with Algorithm set
// to AlgoRandmom // to AlgoRandmom
func (g *Generator) generateRandom() (string, error) { func (g *Generator) generateRandom() (string, error) {
l, err := g.GetPasswordLength() length, err := g.GetPasswordLength()
if err != nil { if err != nil {
return "", fmt.Errorf("failed to calculate password length: %w", err) return "", fmt.Errorf("failed to calculate password length: %w", err)
} }
cr := g.GetCharRangeFromConfig() charRange := g.GetCharRangeFromConfig()
var pw string var password string
var ok bool var ok bool
for !ok { for !ok {
pw, err = g.RandomStringFromCharRange(l, cr) password, err = g.RandomStringFromCharRange(length, charRange)
if err != nil { if err != nil {
return "", err return "", err
} }
ok = g.checkMinimumRequirements(pw) ok = g.checkMinimumRequirements(password)
} }
return pw, nil return password, nil
} }