| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- """
- 密码强度检测服务
- 提供密码强度评估功能
- """
- import re
- from app.schemas.password_strength_schema import (
- PasswordStrengthLevel,
- PasswordStrengthResponse
- )
- class PasswordStrengthService:
- """密码强度检测服务"""
-
- @staticmethod
- def check_password_strength(password: str) -> PasswordStrengthResponse:
- """
- 检测密码强度
-
- 强度等级定义:
- - 弱(weak): 只有小写字母和数字,或单一类型
- - 中(medium): 包含小写字母、数字和特殊符号(至少2种)
- - 强(strong): 包含大小写字母、数字和特殊符号(至少3种,且包含大小写)
-
- Args:
- password: 待检测的密码
-
- Returns:
- PasswordStrengthResponse: 密码强度检测结果
- """
- if not password:
- return PasswordStrengthResponse(
- strength=PasswordStrengthLevel.WEAK,
- score=0,
- suggestions=["密码不能为空"],
- meets_requirements=False
- )
-
- # 检测各种字符类型
- has_lowercase = bool(re.search(r'[a-z]', password))
- has_uppercase = bool(re.search(r'[A-Z]', password))
- has_digit = bool(re.search(r'\d', password))
- has_special = bool(re.search(r'[!@#$%^&*(),.?":{}|<>_\-+=\[\]\\\/;\'`~]', password))
-
- # 计算包含的字符类型数量
- type_count = sum([has_lowercase, has_uppercase, has_digit, has_special])
-
- # 密码长度
- length = len(password)
-
- # 初始化分数和建议
- score = 0
- suggestions = []
-
- # 长度评分 (最多40分)
- if length >= 12:
- score += 40
- elif length >= 8:
- score += 30
- elif length >= 6:
- score += 20
- else:
- score += 10
- suggestions.append("密码长度至少需要8个字符")
-
- # 字符类型评分 (最多60分)
- score += type_count * 15
-
- # 判断强度等级
- strength = PasswordStrengthLevel.WEAK
- meets_requirements = length >= 6 and type_count >= 2
-
- if has_uppercase and has_lowercase and has_digit and has_special and length >= 8:
- # 强:包含大小写字母、数字、特殊符号
- strength = PasswordStrengthLevel.STRONG
- if length < 12:
- suggestions.append("建议密码长度达到12位以上")
- elif type_count >= 2 and length >= 8:
- # 中:至少包含2种字符类型
- strength = PasswordStrengthLevel.MEDIUM
- if not has_uppercase:
- suggestions.append("添加大写字母可以提高密码强度")
- if not has_special:
- suggestions.append("添加特殊符号可以提高密码强度")
- if not (has_uppercase and has_lowercase):
- suggestions.append("同时包含大小写字母可以提高密码强度")
- else:
- # 弱:其他情况
- strength = PasswordStrengthLevel.WEAK
- if not has_lowercase:
- suggestions.append("请添加小写字母")
- if not has_digit:
- suggestions.append("请添加数字")
- if not has_special:
- suggestions.append("请添加特殊符号(如 !@#$%^&*)")
- if not has_uppercase:
- suggestions.append("请添加大写字母")
-
- # 检查常见弱密码模式
- common_patterns = [
- r'12345', r'password', r'qwerty', r'abc', r'111', r'000',
- r'admin', r'user', r'test', r'123456'
- ]
- for pattern in common_patterns:
- if re.search(pattern, password.lower()):
- score = max(0, score - 20)
- suggestions.append("避免使用常见的密码模式")
- strength = PasswordStrengthLevel.WEAK
- break
-
- # 确保分数在0-100之间
- score = max(0, min(100, score))
-
- return PasswordStrengthResponse(
- strength=strength,
- score=score,
- suggestions=suggestions,
- meets_requirements=meets_requirements
- )
|