""" 密码强度检测服务 提供密码强度评估功能 """ 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 )