github.com/tommi2day/gomodules/pwlib@v0.0.0-20230217211148-82cdbcf0a79d/password_generate.go (about)

     1  package pwlib
     2  
     3  import (
     4  	"crypto/rand"
     5  	"fmt"
     6  	"math/big"
     7  
     8  	log "github.com/sirupsen/logrus"
     9  )
    10  
    11  // generateRandomString generate a randow string with the given length and out of allowed charset
    12  func generateRandomString(length int, allowedChars string) string {
    13  	letters := allowedChars
    14  	ret := make([]byte, length)
    15  	for i := 0; i < length; i++ {
    16  		num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
    17  		ret[i] = letters[num.Int64()]
    18  	}
    19  	log.Debugf("Password candidate: %s", string(ret))
    20  	return string(ret)
    21  }
    22  
    23  // GenPassword generates a password with the given complexity
    24  func GenPassword(length int, upper int, lower int, numeric int, special int, firstCharCheck bool) (string, error) {
    25  	log.Debug("GenPassword entered")
    26  	// allowed chars
    27  	var ok = false
    28  	var err error
    29  
    30  	var allowedChars = ""
    31  	// define allowed charset based on parameters
    32  	if upper > 0 {
    33  		allowedChars += UpperChar
    34  	}
    35  	if lower > 0 {
    36  		allowedChars += LowerChar
    37  	}
    38  	if numeric > 0 {
    39  		allowedChars += Digits
    40  	}
    41  	if special > 0 {
    42  		allowedChars += SpecialChar
    43  	}
    44  
    45  	newPassword := ""
    46  	// max 50 tries to generate a valid password
    47  	for c := 0; c < 50; c++ {
    48  		newPassword = generateRandomString(length, allowedChars)
    49  		ok = DoPasswordCheck(newPassword, length, upper, lower, numeric, special, firstCharCheck, allowedChars)
    50  		if ok {
    51  			break
    52  		}
    53  		newPassword = ""
    54  		log.Debugf("generate retry %d", c)
    55  	}
    56  
    57  	if !ok {
    58  		err = fmt.Errorf("unable to create required Password")
    59  	} else {
    60  		log.Debug("Generation succeeded")
    61  	}
    62  	return newPassword, err
    63  }