package utils import ( "errors" "regexp" "unicode" "golang.org/x/crypto/bcrypt" ) var ( ErrPasswordTooShort = errors.New("密码长度至少为8个字符") ErrPasswordNoUpper = errors.New("密码必须包含至少一个大写字母") ErrPasswordNoLower = errors.New("密码必须包含至少一个小写字母") ErrPasswordNoDigit = errors.New("密码必须包含至少一个数字") ErrPasswordNoSpecial = errors.New("密码必须包含至少一个特殊字符") ErrPasswordCommon = errors.New("密码不能是常见弱密码") ErrPasswordSameChars = errors.New("密码不能全部是相同字符") ) // 常见弱密码列表 var commonPasswords = []string{ "password", "12345678", "123456789", "1234567890", "qwerty", "abc123", "password123", "admin123", "123456", "1234567", "12345", "1234", "admin", "root", "user", "test", } // ValidatePasswordStrength 验证密码强度 func ValidatePasswordStrength(password string) error { // 检查长度 if len(password) < 8 { return ErrPasswordTooShort } // 检查是否全部相同字符 allSame := true for i := 1; i < len(password); i++ { if password[i] != password[0] { allSame = false break } } if allSame { return ErrPasswordSameChars } // 检查是否包含大写字母 hasUpper := false // 检查是否包含小写字母 hasLower := false // 检查是否包含数字 hasDigit := false // 检查是否包含特殊字符 hasSpecial := false for _, char := range password { switch { case unicode.IsUpper(char): hasUpper = true case unicode.IsLower(char): hasLower = true case unicode.IsDigit(char): hasDigit = true case unicode.IsPunct(char) || unicode.IsSymbol(char): hasSpecial = true } } if !hasUpper { return ErrPasswordNoUpper } if !hasLower { return ErrPasswordNoLower } if !hasDigit { return ErrPasswordNoDigit } if !hasSpecial { return ErrPasswordNoSpecial } // 检查是否是常见弱密码 lowerPassword := regexp.MustCompile(`[^a-z]`).ReplaceAllString(password, "") for _, common := range commonPasswords { if lowerPassword == common { return ErrPasswordCommon } } return nil } // HashPassword 加密密码 func HashPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) return string(bytes), err } // CheckPassword 验证密码 func CheckPassword(password, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil }