char mins done; need to shuffle some error condition checks before
This commit is contained in:
@@ -36,7 +36,7 @@ func (o *GenOpts) Generate() (passwords []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// generatePassword generates a single password from CharSet c.
|
||||
// generatePassword generates a single password from CharSet c (plus any minimum requirements).
|
||||
func (o *GenOpts) generatePassword(c CharSet) (password string, err error) {
|
||||
|
||||
var maxMin uint
|
||||
@@ -44,9 +44,33 @@ func (o *GenOpts) generatePassword(c CharSet) (password string, err error) {
|
||||
var passLenGap uint
|
||||
var passLen int
|
||||
var passAlloc []rune
|
||||
var filter *selectFilter = o.getFilter()
|
||||
var isDisabled bool
|
||||
|
||||
// Sanity checks/error conditions.
|
||||
maxMin = o.CountUpper + o.CountLower + o.CountSymbols + o.CountExtended
|
||||
if o.explicitCharset != nil && len(o.explicitCharset) != 0 {
|
||||
if o.CountUpper > 0 && !o.Alpha {
|
||||
err = ErrIncompatCharsetFilter
|
||||
return
|
||||
}
|
||||
if o.CountLower > 0 && !o.Alpha {
|
||||
err = ErrIncompatCharsetFilter
|
||||
return
|
||||
}
|
||||
if o.CountNumbers > 0 && !o.Numeric {
|
||||
err = ErrIncompatCharsetFilter
|
||||
return
|
||||
}
|
||||
if o.CountSymbols > 0 && !o.Symbols {
|
||||
err = ErrIncompatCharsetFilter
|
||||
return
|
||||
}
|
||||
if o.CountExtended > 0 && !o.ExtendedSymbols {
|
||||
err = ErrIncompatCharsetFilter
|
||||
return
|
||||
}
|
||||
}
|
||||
maxMin = o.CountUpper + o.CountLower + o.CountNumbers + o.CountSymbols + o.CountExtended
|
||||
if maxMin > o.LengthMax {
|
||||
err = ErrTooSmall
|
||||
return
|
||||
@@ -71,11 +95,93 @@ func (o *GenOpts) generatePassword(c CharSet) (password string, err error) {
|
||||
// And make the rune slice of that length.
|
||||
passAlloc = make([]rune, passLen)
|
||||
|
||||
for idx, _ := range passAlloc {
|
||||
idx := 0
|
||||
for idx < passLen {
|
||||
var char Char
|
||||
|
||||
if o.explicitCharset != nil && len(o.explicitCharset) != 0 {
|
||||
// Add upperCounter chars (if necessary).
|
||||
for filter.upperCounter > 0 {
|
||||
if char, err = upper.RandChar(); err != nil {
|
||||
continue
|
||||
}
|
||||
if isDisabled, err = o.DisabledChars.Has(char); err != nil || isDisabled {
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
passAlloc[idx] = rune(char)
|
||||
filter.upperCounter--
|
||||
idx++
|
||||
continue
|
||||
}
|
||||
// Add lowerCounter chars (if necessary).
|
||||
for filter.lowerCounter > 0 {
|
||||
if char, err = lower.RandChar(); err != nil {
|
||||
continue
|
||||
}
|
||||
if isDisabled, err = o.DisabledChars.Has(char); err != nil || isDisabled {
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
passAlloc[idx] = rune(char)
|
||||
filter.lowerCounter--
|
||||
idx++
|
||||
continue
|
||||
}
|
||||
// Add numberCounter chars (if necessary).
|
||||
for filter.numberCounter > 0 {
|
||||
if char, err = numeric.RandChar(); err != nil {
|
||||
continue
|
||||
}
|
||||
if isDisabled, err = o.DisabledChars.Has(char); err != nil || isDisabled {
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
passAlloc[idx] = rune(char)
|
||||
filter.numberCounter--
|
||||
idx++
|
||||
continue
|
||||
}
|
||||
// Add symbolCounter chars (if necessary).
|
||||
for filter.symbolCounter > 0 {
|
||||
if char, err = symbols.RandChar(); err != nil {
|
||||
continue
|
||||
}
|
||||
if isDisabled, err = o.DisabledChars.Has(char); err != nil || isDisabled {
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
passAlloc[idx] = rune(char)
|
||||
filter.symbolCounter--
|
||||
idx++
|
||||
continue
|
||||
}
|
||||
// Add extendedCounter chars (if necessary).
|
||||
for filter.extendedCounter > 0 {
|
||||
if char, err = extendedSymbols.RandChar(); err != nil {
|
||||
continue
|
||||
}
|
||||
if isDisabled, err = o.DisabledChars.Has(char); err != nil || isDisabled {
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
passAlloc[idx] = rune(char)
|
||||
filter.extendedCounter--
|
||||
idx++
|
||||
continue
|
||||
}
|
||||
|
||||
// Break here if we've reached the full password with just the filter.
|
||||
if idx > passLen {
|
||||
err = ErrTooSmall
|
||||
return
|
||||
} else if idx == passLen {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Minimum requirements satisfied; continue with default GenOpts-specific charset.
|
||||
for {
|
||||
var isDisabled bool
|
||||
|
||||
if char, err = c.RandChar(); err != nil {
|
||||
return
|
||||
@@ -86,11 +192,13 @@ func (o *GenOpts) generatePassword(c CharSet) (password string, err error) {
|
||||
}
|
||||
|
||||
passAlloc[idx] = rune(char)
|
||||
idx++
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
password = string(passAlloc)
|
||||
passwordShuffle(&password)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -182,3 +290,17 @@ func (o *GenOpts) UnsetExplicitCharset() {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// getFilter gets a filter counter.
|
||||
func (o *GenOpts) getFilter() (f *selectFilter) {
|
||||
|
||||
f = &selectFilter{
|
||||
upperCounter: o.CountUpper,
|
||||
lowerCounter: o.CountLower,
|
||||
numberCounter: o.CountNumbers,
|
||||
symbolCounter: o.CountSymbols,
|
||||
extendedCounter: o.CountExtended,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user