目录
密码强度
在涉及修改密码的场景中,密码强度(也称密码安全性)校验是绕不开的话题。一个密码的安全性除了与密码长度相关外,也与密码所采用的字符种类有关。在不考虑密码长度的情况下,密码强度通常分为以下五类(由高到低排序):
密码强度 | 说明 | 示例 |
S | 密码中必须存在特殊字符、大小写字母和数字 | Csdn#2020 |
A |
对特殊字符、大写字母、小写字母和数字至少存在3种 |
csdn#2020 |
B | 对特殊字符、大写字母、小写字母和数字至少存在2种 | csdn2020 |
C | 对特殊字符、大写字母、小写字母和数字至少存在1种 | csdn |
D | 不存在特殊字符、大小写字母和数字。 | /、\ |
💡提示:特殊字符集假定为 ~!@#$%^&*?_-
解决方案
检测密码强度包含两个方面,一个是密码长度,另一个是包含的字符种类。对不符合长度要求的密码和字符种类范围低的密码报错返回。
代码
package check_pwd
import (
"fmt"
"regexp"
)
const (
levelD = iota
LevelC
LevelB
LevelA
LevelS
)
func Check(minLength, maxLength, minLevel int, pwd string) error {
if len(pwd) < minLength {
return fmt.Errorf("BAD PASSWORD: The password is shorter than %d characters", minLength)
}
if len(pwd) > maxLength {
return fmt.Errorf("BAD PASSWORD: The password is logner than %d characters", maxLength)
}
var level int = levelD
patternList := []string{`[0-9]+`, `[a-z]+`, `[A-Z]+`, `[~!@#$%^&*?_-]+`}
for _, pattern := range patternList {
match, _ := regexp.MatchString(pattern, pwd)
if match {
level++
}
}
if level < minLevel {
return fmt.Errorf("The password does not satisfy the current policy requirements. ")
}
return nil
}
代码走读
package check_pwd import ( "fmt" "regexp" ) // 密码强度等级,D为最低 const ( levelD = iota LevelC LevelB LevelA LevelS ) /* * minLength: 指定密码的最小长度 * maxLength:指定密码的最大长度 * minLevel:指定密码最低要求的强度等级 * pwd:明文密码 */ func Check(minLength, maxLength, minLevel int, pwd string) error { // 首先校验密码长度是否在范围内 if len(pwd) < minLength { return fmt.Errorf("BAD PASSWORD: The password is shorter than %d characters", minLength) } if len(pwd) > maxLength { return fmt.Errorf("BAD PASSWORD: The password is logner than %d characters", maxLength) } // 初始化密码强度等级为D,利用正则校验密码强度,若匹配成功则强度自增1 var level int = levelD patternList := []string{`[0-9]+`, `[a-z]+`, `[A-Z]+`, `[~!@#$%^&*?_-]+`} for _, pattern := range patternList { match, _ := regexp.MatchString(pattern, pwd) if match { level++ } } // 如果最终密码强度低于要求的最低强度,返回并报错 if level < minLevel { return fmt.Errorf("The password does not satisfy the current policy requirements. ") } return nil }