Split up functions into seperate files

This commit is contained in:
Winni Neessen 2021-03-21 14:05:14 +01:00
parent 3a87ae7829
commit eb221ccc69
Signed by: wneessen
GPG key ID: 385AC9889632126E
5 changed files with 181 additions and 97 deletions

View file

@ -83,7 +83,7 @@ clean: # @HELP removes built binaries and temporary files
clean: bin-clean
bin-clean:
rm -rf .go bin
rm -rf .go bin *.exe
help: # @HELP prints this message
help:

102
apg.go
View file

@ -1,17 +1,14 @@
package main
import (
"crypto/rand"
"flag"
"fmt"
"math/big"
"os"
"regexp"
)
// Constants
const DefaultPwLenght int = 20
const VersionString string = "0.2.3"
const VersionString string = "0.2.4"
const PwLowerCharsHuman string = "abcdefghjkmnpqrstuvwxyz"
const PwUpperCharsHuman string = "ABCDEFGHJKMNPQRSTUVWXYZ"
const PwLowerChars string = "abcdefghijklmnopqrstuvwxyz"
@ -32,6 +29,7 @@ type cliOpts struct {
useSpecial bool
humanReadable bool
excludeChars string
newStyleModes string
showHelp bool
showVersion bool
}
@ -56,6 +54,8 @@ func init() {
// String flags
flag.StringVar(&config.excludeChars, "E", "", "Exclude list of characters from generated password")
flag.StringVar(&config.newStyleModes, "M", "",
"New style password parameters (higher priority than single parameters)")
flag.Parse()
if config.showVersion {
@ -66,21 +66,8 @@ func init() {
// Main function that generated the passwords and returns them
func main() {
pwLength := config.minPassLen
if pwLength < config.minPassLen {
pwLength = config.minPassLen
}
if pwLength > config.maxPassLen {
pwLength = config.maxPassLen
}
if config.useComplex {
config.useUpperCase = true
config.useLowerCase = true
config.useSpecial = true
config.useNumber = true
config.humanReadable = false
}
parseParams()
pwLength := getPwLengthFromParams()
charRange := getCharRange()
for i := 1; i <= config.numOfPass; i++ {
@ -92,80 +79,3 @@ func main() {
fmt.Println(pwString)
}
}
// Provide the range of available characters based on provided parameters
func getCharRange() string {
pwUpperChars := PwUpperChars
pwLowerChars := PwLowerChars
pwNumbers := PwNumbers
pwSpecialChars := PwSpecialChars
if config.humanReadable {
pwUpperChars = PwUpperCharsHuman
pwLowerChars = PwLowerCharsHuman
pwNumbers = PwNumbersHuman
pwSpecialChars = PwSpecialCharsHuman
}
var charRange string
if config.useLowerCase {
charRange = charRange + pwLowerChars
}
if config.useUpperCase {
charRange = charRange + pwUpperChars
}
if config.useNumber {
charRange = charRange + pwNumbers
}
if config.useSpecial {
charRange = charRange + pwSpecialChars
}
if config.excludeChars != "" {
regExp := regexp.MustCompile("[" + config.excludeChars + "]")
charRange = regExp.ReplaceAllLiteralString(charRange, "")
}
return charRange
}
// Generate random characters based on given character range
// and password length
func getRandChar(charRange *string, pwLength int) (string, error) {
if pwLength <= 0 {
err := fmt.Errorf("provided pwLength value is <= 0: %v", pwLength)
return "", err
}
availCharsLength := len(*charRange)
charSlice := []byte(*charRange)
returnString := make([]byte, pwLength)
for i := 0; i < pwLength; i++ {
randNum, err := getRandNum(availCharsLength)
if err != nil {
return "", err
}
returnString[i] = charSlice[randNum]
}
return string(returnString), nil
}
// Generate a random number with given maximum value
func getRandNum(maxNum int) (int, error) {
if maxNum <= 0 {
err := fmt.Errorf("provided maxNum is <= 0: %v", maxNum)
return 0, err
}
maxNumBigInt := big.NewInt(int64(maxNum))
if !maxNumBigInt.IsUint64() {
err := fmt.Errorf("big.NewInt() generation returned negative value: %v", maxNumBigInt)
return 0, err
}
randNum64, err := rand.Int(rand.Reader, maxNumBigInt)
if err != nil {
return 0, err
}
randNum := int(randNum64.Int64())
if randNum < 0 {
err := fmt.Errorf("generated random number does not fit as int64: %v", randNum64)
return 0, err
}
return randNum, nil
}

37
chars.go Normal file
View file

@ -0,0 +1,37 @@
package main
import "regexp"
// Provide the range of available characters based on provided parameters
func getCharRange() string {
pwUpperChars := PwUpperChars
pwLowerChars := PwLowerChars
pwNumbers := PwNumbers
pwSpecialChars := PwSpecialChars
if config.humanReadable {
pwUpperChars = PwUpperCharsHuman
pwLowerChars = PwLowerCharsHuman
pwNumbers = PwNumbersHuman
pwSpecialChars = PwSpecialCharsHuman
}
var charRange string
if config.useLowerCase {
charRange = charRange + pwLowerChars
}
if config.useUpperCase {
charRange = charRange + pwUpperChars
}
if config.useNumber {
charRange = charRange + pwNumbers
}
if config.useSpecial {
charRange = charRange + pwSpecialChars
}
if config.excludeChars != "" {
regExp := regexp.MustCompile("[" + config.excludeChars + "]")
charRange = regExp.ReplaceAllLiteralString(charRange, "")
}
return charRange
}

87
params.go Normal file
View file

@ -0,0 +1,87 @@
package main
import (
"fmt"
"os"
)
// Parse the new style parameters
func parseNewStyleParams() {
for _, curParam := range config.newStyleModes {
switch curParam {
case 'S':
config.useSpecial = true
break
case 's':
config.useSpecial = false
break
case 'N':
config.useNumber = true
break
case 'n':
config.useNumber = false
break
case 'L':
config.useLowerCase = true
break
case 'l':
config.useLowerCase = false
break
case 'U':
config.useUpperCase = true
break
case 'u':
config.useUpperCase = false
break
case 'H':
config.humanReadable = true
break
case 'h':
config.humanReadable = false
break
// APG compatbilitly
case 'C':
config.useUpperCase = true
break
case 'c':
config.useUpperCase = false
break
default:
fmt.Printf("Unknown password style parameter: %q\n", string(curParam))
os.Exit(1)
}
}
}
func getPwLengthFromParams() int {
pwLength := config.minPassLen
if pwLength < config.minPassLen {
pwLength = config.minPassLen
}
if pwLength > config.maxPassLen {
pwLength = config.maxPassLen
}
return pwLength
}
func parseParams() {
if config.useComplex {
config.useUpperCase = true
config.useLowerCase = true
config.useSpecial = true
config.useNumber = true
config.humanReadable = false
}
if config.newStyleModes != "" {
parseNewStyleParams()
}
if config.useUpperCase == false &&
config.useLowerCase == false &&
config.useNumber == false &&
config.useSpecial == false {
fmt.Printf("No password mode set. Cannot generate password from empty character set.")
os.Exit(1)
}
}

50
rand.go Normal file
View file

@ -0,0 +1,50 @@
package main
import (
"crypto/rand"
"fmt"
"math/big"
)
// Generate random characters based on given character range
// and password length
func getRandChar(charRange *string, pwLength int) (string, error) {
if pwLength <= 0 {
err := fmt.Errorf("provided pwLength value is <= 0: %v", pwLength)
return "", err
}
availCharsLength := len(*charRange)
charSlice := []byte(*charRange)
returnString := make([]byte, pwLength)
for i := 0; i < pwLength; i++ {
randNum, err := getRandNum(availCharsLength)
if err != nil {
return "", err
}
returnString[i] = charSlice[randNum]
}
return string(returnString), nil
}
// Generate a random number with given maximum value
func getRandNum(maxNum int) (int, error) {
if maxNum <= 0 {
err := fmt.Errorf("provided maxNum is <= 0: %v", maxNum)
return 0, err
}
maxNumBigInt := big.NewInt(int64(maxNum))
if !maxNumBigInt.IsUint64() {
err := fmt.Errorf("big.NewInt() generation returned negative value: %v", maxNumBigInt)
return 0, err
}
randNum64, err := rand.Int(rand.Reader, maxNumBigInt)
if err != nil {
return 0, err
}
randNum := int(randNum64.Int64())
if randNum < 0 {
err := fmt.Errorf("generated random number does not fit as int64: %v", randNum64)
return 0, err
}
return randNum, nil
}