2023-08-04 16:02:58 +02:00
|
|
|
package apg
|
|
|
|
|
2023-08-04 18:38:32 +02:00
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
)
|
2023-08-04 17:14:24 +02:00
|
|
|
|
2023-08-04 16:02:58 +02:00
|
|
|
// Mode represents a mode of characters
|
|
|
|
type Mode uint8
|
|
|
|
|
2023-08-04 17:14:24 +02:00
|
|
|
// ModeMask represents a bitmask of character modes
|
|
|
|
type ModeMask uint8
|
|
|
|
|
2023-08-04 16:02:58 +02:00
|
|
|
const (
|
2023-08-05 17:54:41 +02:00
|
|
|
// ModeNumeric sets the bitmask to include numeric in the generated passwords
|
|
|
|
ModeNumeric = 1 << iota
|
2023-08-04 16:02:58 +02:00
|
|
|
// ModeLowerCase sets the bitmask to include lower case characters in the
|
|
|
|
// generated passwords
|
|
|
|
ModeLowerCase
|
|
|
|
// ModeUpperCase sets the bitmask to include upper case characters in the
|
|
|
|
// generated passwords
|
|
|
|
ModeUpperCase
|
|
|
|
// ModeSpecial sets the bitmask to include special characters in the
|
|
|
|
// generated passwords
|
|
|
|
ModeSpecial
|
|
|
|
// ModeHumanReadable sets the bitmask to generate human readable passwords
|
|
|
|
ModeHumanReadable
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// CharRangeAlphaLower represents all lower-case alphabetical characters
|
|
|
|
CharRangeAlphaLower = "abcdefghijklmnopqrstuvwxyz"
|
|
|
|
// CharRangeAlphaLowerHuman represents the human-readable lower-case alphabetical characters
|
|
|
|
CharRangeAlphaLowerHuman = "abcdefghjkmnpqrstuvwxyz"
|
|
|
|
// CharRangeAlphaUpper represents all upper-case alphabetical characters
|
|
|
|
CharRangeAlphaUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
|
// CharRangeAlphaUpperHuman represents the human-readable upper-case alphabetical characters
|
|
|
|
CharRangeAlphaUpperHuman = "ABCDEFGHJKMNPQRSTUVWXYZ"
|
2023-08-05 17:54:41 +02:00
|
|
|
// CharRangeNumeric represents all numerical characters
|
|
|
|
CharRangeNumeric = "1234567890"
|
2023-08-06 18:55:47 +02:00
|
|
|
// CharRangeNumericHuman represents all human-readable numerical characters
|
|
|
|
CharRangeNumericHuman = "23456789"
|
2023-08-04 16:02:58 +02:00
|
|
|
// CharRangeSpecial represents all special characters
|
|
|
|
CharRangeSpecial = `!\"#$%&'()*+,-./:;<=>?@[\\]^_{|}~`
|
|
|
|
// CharRangeSpecialHuman represents all human-readable special characters
|
|
|
|
CharRangeSpecialHuman = `#%*+-:;=`
|
|
|
|
)
|
|
|
|
|
2023-08-04 17:14:24 +02:00
|
|
|
// MaskSetMode sets a specific Mode to a given Mode bitmask
|
|
|
|
func MaskSetMode(ma ModeMask, mo Mode) ModeMask { return ModeMask(uint8(ma) | uint8(mo)) }
|
|
|
|
|
|
|
|
// MaskClearMode clears a specific Mode from a given Mode bitmask
|
|
|
|
func MaskClearMode(ma ModeMask, mo Mode) ModeMask { return ModeMask(uint8(ma) &^ uint8(mo)) }
|
|
|
|
|
|
|
|
// MaskToggleMode toggles a specific Mode in a given Mode bitmask
|
|
|
|
func MaskToggleMode(ma ModeMask, mo Mode) ModeMask { return ModeMask(uint8(ma) ^ uint8(mo)) }
|
|
|
|
|
|
|
|
// 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 {
|
2023-08-04 18:38:32 +02:00
|
|
|
cl := strings.Split(ms, "")
|
2023-08-04 17:14:24 +02:00
|
|
|
var mm ModeMask
|
2023-08-04 18:38:32 +02:00
|
|
|
for _, m := range cl {
|
2023-08-04 17:14:24 +02:00
|
|
|
switch m {
|
|
|
|
case "C":
|
2023-08-05 17:54:41 +02:00
|
|
|
mm = MaskSetMode(mm, ModeLowerCase|ModeNumeric|ModeSpecial|ModeUpperCase)
|
2023-08-04 17:14:24 +02:00
|
|
|
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":
|
2023-08-05 17:54:41 +02:00
|
|
|
mm = MaskClearMode(mm, ModeNumeric)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "N":
|
2023-08-05 17:54:41 +02:00
|
|
|
mm = MaskSetMode(mm, ModeNumeric)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "s":
|
|
|
|
mm = MaskClearMode(mm, ModeSpecial)
|
|
|
|
case "S":
|
|
|
|
mm = MaskSetMode(mm, ModeSpecial)
|
|
|
|
case "u":
|
|
|
|
mm = MaskClearMode(mm, ModeUpperCase)
|
|
|
|
case "U":
|
|
|
|
mm = MaskSetMode(mm, ModeUpperCase)
|
|
|
|
}
|
|
|
|
}
|
2023-08-04 16:02:58 +02:00
|
|
|
|
2023-08-04 17:14:24 +02:00
|
|
|
return mm
|
|
|
|
}
|
2023-08-04 16:02:58 +02:00
|
|
|
|
2023-08-04 17:14:24 +02:00
|
|
|
// 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"
|
2023-08-05 17:54:41 +02:00
|
|
|
case ModeNumeric:
|
|
|
|
return "Numeric"
|
2023-08-04 17:14:24 +02:00
|
|
|
case ModeSpecial:
|
|
|
|
return "Special"
|
|
|
|
case ModeUpperCase:
|
|
|
|
return "Upper-case"
|
|
|
|
default:
|
|
|
|
return "Unknown"
|
|
|
|
}
|
|
|
|
}
|