package validator import ( "unicode/utf8" "github.com/break/junhong_cmp_fiber/pkg/errors" ) const ( // LoginPasswordMinLength 登录密码最小长度 LoginPasswordMinLength = 8 // LoginPasswordMaxLength 登录密码最大长度 LoginPasswordMaxLength = 12 // loginPasswordMinCategories 大写、小写、数字、特殊符号四类中至少需要的类数 loginPasswordMinCategories = 3 ) // ValidateLoginPassword 校验设置或修改登录密码时的统一规则。 // label 为提示中的字段名(如“密码”“新密码”);消息只描述规则,不回显密码。 // 长度不符返回 CodeInvalidParam,含不允许字符或类别不足返回 CodePasswordTooWeak。 func ValidateLoginPassword(label, password string) error { length := utf8.RuneCountInString(password) if length < LoginPasswordMinLength || length > LoginPasswordMaxLength { return errors.New(errors.CodeInvalidParam, label+"长度须为 8~12 位") } var hasUpper, hasLower, hasDigit, hasSymbol bool for i := 0; i < len(password); i++ { ch := password[i] switch { case ch <= ' ' || ch > '~': return errors.New(errors.CodePasswordTooWeak, label+"只能包含字母、数字和特殊符号") case ch >= 'A' && ch <= 'Z': hasUpper = true case ch >= 'a' && ch <= 'z': hasLower = true case ch >= '0' && ch <= '9': hasDigit = true default: hasSymbol = true } } categories := 0 for _, present := range []bool{hasUpper, hasLower, hasDigit, hasSymbol} { if present { categories++ } } if categories < loginPasswordMinCategories { return errors.New(errors.CodePasswordTooWeak, label+"须包含大写字母、小写字母、数字、特殊符号中的至少三类") } return nil }