2024-03-12 20:59:07 +01:00
|
|
|
// SPDX-FileCopyrightText: 2021-2024 Winni Neessen <wn@neessen.dev>
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
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
|
2024-03-08 10:22:20 +01:00
|
|
|
func MaskSetMode(mask ModeMask, mode Mode) ModeMask { return ModeMask(uint8(mask) | uint8(mode)) }
|
2023-08-04 17:14:24 +02:00
|
|
|
|
|
|
|
// MaskClearMode clears a specific Mode from a given Mode bitmask
|
2024-03-08 10:22:20 +01:00
|
|
|
func MaskClearMode(mask ModeMask, mode Mode) ModeMask { return ModeMask(uint8(mask) &^ uint8(mode)) }
|
2023-08-04 17:14:24 +02:00
|
|
|
|
|
|
|
// MaskToggleMode toggles a specific Mode in a given Mode bitmask
|
2024-03-08 10:22:20 +01:00
|
|
|
func MaskToggleMode(mask ModeMask, mode Mode) ModeMask { return ModeMask(uint8(mask) ^ uint8(mode)) }
|
2023-08-04 17:14:24 +02:00
|
|
|
|
|
|
|
// MaskHasMode returns true if a given Mode bitmask holds a specific Mode
|
2024-03-08 10:22:20 +01:00
|
|
|
func MaskHasMode(mask ModeMask, mode Mode) bool { return uint8(mask)&uint8(mode) != 0 }
|
2023-08-04 17:14:24 +02:00
|
|
|
|
2024-03-08 10:22:20 +01:00
|
|
|
func ModesFromFlags(maskString string) ModeMask {
|
|
|
|
cl := strings.Split(maskString, "")
|
|
|
|
var modeMask 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":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskSetMode(modeMask, ModeLowerCase|ModeNumeric|ModeSpecial|ModeUpperCase)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "h":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskClearMode(modeMask, ModeHumanReadable)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "H":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskSetMode(modeMask, ModeHumanReadable)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "l":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskClearMode(modeMask, ModeLowerCase)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "L":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskSetMode(modeMask, ModeLowerCase)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "n":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskClearMode(modeMask, ModeNumeric)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "N":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskSetMode(modeMask, ModeNumeric)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "s":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskClearMode(modeMask, ModeSpecial)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "S":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskSetMode(modeMask, ModeSpecial)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "u":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskClearMode(modeMask, ModeUpperCase)
|
2023-08-04 17:14:24 +02:00
|
|
|
case "U":
|
2024-03-08 10:22:20 +01:00
|
|
|
modeMask = MaskSetMode(modeMask, ModeUpperCase)
|
2023-08-04 17:14:24 +02:00
|
|
|
}
|
|
|
|
}
|
2023-08-04 16:02:58 +02:00
|
|
|
|
2024-03-08 10:22:20 +01:00
|
|
|
return modeMask
|
2023-08-04 17:14:24 +02:00
|
|
|
}
|
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"
|
|
|
|
}
|
|
|
|
}
|