mirror of
https://github.com/wneessen/apg-go.git
synced 2024-12-23 03:30:39 +01:00
Add phonetic spelling functionality to password generator
The update introduces a new 'SpellPassword' setting in the configuration that, when enabled, spells out the generated passwords in the phonetic alphabet. The accompanied changes include the addition of 'spelling.go' and 'spelling_test.go' files containing the spelling logic and corresponding tests. The domain-specific error handling is also enhanced for unsupported characters.
This commit is contained in:
parent
4219a27007
commit
93f092e690
3 changed files with 168 additions and 0 deletions
|
@ -41,6 +41,8 @@ type Config struct {
|
|||
// NumberPass sets the number of passwords that are generated
|
||||
// and returned by the generator
|
||||
NumberPass int64
|
||||
// SpellPassword if set will spell the generated passwords in the phonetic alphabet
|
||||
SpellPassword bool
|
||||
}
|
||||
|
||||
// Option is a function that can override default Config settings
|
||||
|
|
113
spelling.go
Normal file
113
spelling.go
Normal file
|
@ -0,0 +1,113 @@
|
|||
package apg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
symbNumNames = map[byte]string{
|
||||
'1': "ONE",
|
||||
'2': "TWO",
|
||||
'3': "THREE",
|
||||
'4': "FOUR",
|
||||
'5': "FIVE",
|
||||
'6': "SIX",
|
||||
'7': "SEVEN",
|
||||
'8': "EIGHT",
|
||||
'9': "NINE",
|
||||
'0': "ZERO",
|
||||
33: "EXCLAMATION_POINT",
|
||||
34: "QUOTATION_MARK",
|
||||
35: "CROSSHATCH",
|
||||
36: "DOLLAR_SIGN",
|
||||
37: "PERCENT_SIGN",
|
||||
38: "AMPERSAND",
|
||||
39: "APOSTROPHE",
|
||||
40: "LEFT_PARENTHESIS",
|
||||
41: "RIGHT_PARENTHESIS",
|
||||
42: "ASTERISK",
|
||||
43: "PLUS_SIGN",
|
||||
44: "COMMA",
|
||||
45: "HYPHEN",
|
||||
46: "PERIOD",
|
||||
47: "SLASH",
|
||||
58: "COLON",
|
||||
59: "SEMICOLON",
|
||||
60: "LESS_THAN",
|
||||
61: "EQUAL_SIGN",
|
||||
62: "GREATER_THAN",
|
||||
63: "QUESTION_MARK",
|
||||
64: "AT_SIGN",
|
||||
91: "LEFT_BRACKET",
|
||||
92: "BACKSLASH",
|
||||
93: "RIGHT_BRACKET",
|
||||
94: "CIRCUMFLEX",
|
||||
95: "UNDERSCORE",
|
||||
96: "GRAVE",
|
||||
123: "LEFT_BRACE",
|
||||
124: "VERTICAL_BAR",
|
||||
125: "RIGHT_BRACE",
|
||||
126: "TILDE",
|
||||
}
|
||||
alphabetNames = map[byte]string{
|
||||
'A': "Alfa",
|
||||
'B': "Bravo",
|
||||
'C': "Charlie",
|
||||
'D': "Delta",
|
||||
'E': "Echo",
|
||||
'F': "Foxtrot",
|
||||
'G': "Golf",
|
||||
'H': "Hotel",
|
||||
'I': "India",
|
||||
'J': "Juliett",
|
||||
'K': "Kilo",
|
||||
'L': "Lima",
|
||||
'M': "Mike",
|
||||
'N': "November",
|
||||
'O': "Oscar",
|
||||
'P': "Papa",
|
||||
'Q': "Quebec",
|
||||
'R': "Romeo",
|
||||
'S': "Sierra",
|
||||
'T': "Tango",
|
||||
'U': "Uniform",
|
||||
'V': "Victor",
|
||||
'W': "Whiskey",
|
||||
'X': "X_ray",
|
||||
'Y': "Yankee",
|
||||
'Z': "Zulu",
|
||||
}
|
||||
)
|
||||
|
||||
// Spell returns a given string as spelled english phonetic alphabet string
|
||||
func Spell(input string) (string, error) {
|
||||
var returnString []string
|
||||
for _, curChar := range input {
|
||||
curSpellString, err := ConvertByteToWord(byte(curChar))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
returnString = append(returnString, curSpellString)
|
||||
}
|
||||
return strings.Join(returnString, "/"), nil
|
||||
}
|
||||
|
||||
// ConvertByteToWord converts a given ASCII byte into the corresponding spelled version
|
||||
// of the english phonetic alphabet
|
||||
func ConvertByteToWord(charByte byte) (string, error) {
|
||||
var returnString string
|
||||
switch {
|
||||
case charByte > 64 && charByte < 91:
|
||||
returnString = alphabetNames[charByte]
|
||||
case charByte > 96 && charByte < 123:
|
||||
returnString = strings.ToLower(alphabetNames[charByte-32])
|
||||
default:
|
||||
returnString = symbNumNames[charByte]
|
||||
}
|
||||
|
||||
if returnString == "" {
|
||||
return "", fmt.Errorf("failed to convert given byte to word: %s is unsupported", string(charByte))
|
||||
}
|
||||
return returnString, nil
|
||||
}
|
53
spelling_test.go
Normal file
53
spelling_test.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package apg
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConvertByteToWord(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
char byte
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "UpperCaseChar",
|
||||
char: 'A',
|
||||
want: alphabetNames['A'],
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "LowerCaseChar",
|
||||
char: 'a',
|
||||
want: strings.ToLower(alphabetNames['A']),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "NonAlphaChar",
|
||||
char: '(',
|
||||
want: symbNumNames['('],
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "UnsupportedChar",
|
||||
char: 'ü',
|
||||
want: "",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := ConvertByteToWord(tt.char)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ConvertByteToWord() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("ConvertByteToWord() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue