From 510f9c21881dcfc4ce02909f8d453c92ac01d918 Mon Sep 17 00:00:00 2001 From: Liam Burnand Date: Sat, 15 Feb 2025 18:05:48 +0000 Subject: [PATCH] Modifying to be more simplistic to use --- utils/hash.go | 79 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/utils/hash.go b/utils/hash.go index e8d7eee..3954aa8 100644 --- a/utils/hash.go +++ b/utils/hash.go @@ -3,22 +3,35 @@ package utils import ( "crypto/rand" "encoding/hex" + "errors" "fmt" "math/big" whirl "github.com/balacode/zr-whirl" ) -type Type int +type ( + Type int + Length int + Characters string +) const ( GeneratePassword Type = iota GenerateSalt + GenerateUsername +) + +const ( + UsernameCharacters Characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + SaltCharacters Characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/." + PasswordCharacters Characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@*()&" ) const ( - saltCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/." - passwordCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@*()&" + PasswordLength Length = 12 + SaltLength Length = 22 + UsernameLength Length = 20 ) // HashPass hashes a password using a Whirlpool hash. @@ -37,37 +50,71 @@ func HashPass(password string) string { return next } +func GenerateRandomLength(length int, randomType Type) (string, error) { + if length < 6 || length > 40 { + return "", errors.New("length must be between 6 and 40") + } + switch randomType { + case GeneratePassword: + b, err := rangeLoop(PasswordCharacters, Length(length)) + if err != nil { + return "", fmt.Errorf("error generating random password: %w", err) + } + + return b, nil + case GenerateSalt: + b, err := rangeLoop(SaltCharacters, Length(length)) + if err != nil { + return "", fmt.Errorf("error generating random salt: %w", err) + } + + return "$2a$06$" + b, nil + case GenerateUsername: + b, err := rangeLoop(UsernameCharacters, Length(length)) + if err != nil { + return "", fmt.Errorf("error generating random username: %w", err) + } + + return b, nil + default: + return "", fmt.Errorf("invalid type: %d", randomType) + } +} + // GenerateRandom generates a random string for either password or salt func GenerateRandom(randomType Type) (string, error) { switch randomType { case GeneratePassword: - lenPass := big.NewInt(int64(len(passwordCharacters))) - passwordLength := 12 - - b, err := rangeLoop(lenPass, passwordLength) + b, err := rangeLoop(PasswordCharacters, PasswordLength) if err != nil { - return "", fmt.Errorf("error generating random: %w", err) + return "", fmt.Errorf("error generating random password: %w", err) } return b, nil case GenerateSalt: - lenSalt := big.NewInt(int64(len(saltCharacters))) - saltLength := 22 - - b, err := rangeLoop(lenSalt, saltLength) + b, err := rangeLoop(SaltCharacters, SaltLength) if err != nil { - return "", fmt.Errorf("error generating random: %w", err) + return "", fmt.Errorf("error generating random salt: %w", err) } return "$2a$06$" + b, nil + case GenerateUsername: + b, err := rangeLoop(UsernameCharacters, UsernameLength) + if err != nil { + return "", fmt.Errorf("error generating random username: %w", err) + } + + return b, nil default: return "", fmt.Errorf("invalid type: %d", randomType) } } // rangeLoop creates the random string that will be used -func rangeLoop(length *big.Int, size int) (string, error) { - bytes := make([]byte, size) +func rangeLoop(characters Characters, randomLength Length) (string, error) { + bytes := make([]byte, randomLength) + + length := big.NewInt(int64(len(characters))) for i := range bytes { randInt, err := rand.Int(rand.Reader, length) @@ -75,7 +122,7 @@ func rangeLoop(length *big.Int, size int) (string, error) { return "", err } - bytes[i] = passwordCharacters[randInt.Int64()] + bytes[i] = characters[randInt.Int64()] } return string(bytes), nil