""" 身份证号验证服务 提供严格的身份证号码校验,包括: - 格式校验(18位) - 出生日期校验 - 校验码验证(ISO 7064:1983.MOD 11-2) """ import re from datetime import datetime class IDCardValidator: """身份证号验证器""" # 加权因子 WEIGHT_FACTORS = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] # 校验码对应值 CHECK_CODES = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'] @staticmethod def validate_format(id_card: str) -> tuple[bool, str]: """ 验证身份证号格式 Returns: (是否有效, 错误信息) """ # 必须是18位 if len(id_card) != 18: return False, "身份证号必须为18位" # 前17位必须是数字,最后一位是数字或X if not re.match(r'^\d{17}[\dXx]$', id_card): return False, "身份证号格式不正确" return True, "" @staticmethod def validate_birth_date(id_card: str) -> tuple[bool, str]: """ 验证出生日期 Args: id_card: 18位身份证号 Returns: (是否有效, 错误信息) """ # 提取出生日期(第7-14位) year = id_card[6:10] month = id_card[10:12] day = id_card[12:14] # 验证年份(1900-当前年份) try: year_int = int(year) current_year = datetime.now().year if year_int < 1900 or year_int > current_year: return False, f"出生年份不合法(应在1900-{current_year}之间)" except ValueError: return False, "出生年份格式错误" # 验证月份(01-12) try: month_int = int(month) if month_int < 1 or month_int > 12: return False, "出生月份不合法(应在01-12之间)" except ValueError: return False, "出生月份格式错误" # 验证日期 try: birth_date = datetime(year_int, month_int, int(day)) # 不能是未来日期 if birth_date > datetime.now(): return False, "出生日期不能是未来日期" except ValueError: return False, "出生日期不合法" return True, "" @staticmethod def validate_check_code(id_card: str) -> tuple[bool, str]: """ 验证校验码(ISO 7064:1983.MOD 11-2) Args: id_card: 18位身份证号 Returns: (是否有效, 错误信息) """ # 计算校验码 sum_value = 0 for i in range(17): sum_value += int(id_card[i]) * IDCardValidator.WEIGHT_FACTORS[i] # 取模得到校验码索引 check_index = sum_value % 11 expected_check_code = IDCardValidator.CHECK_CODES[check_index] # 比较校验码(不区分大小写) actual_check_code = id_card[17].upper() if actual_check_code != expected_check_code: return False, f"身份证号校验码错误" return True, "" @classmethod def validate(cls, id_card: str) -> tuple[bool, str]: """ 完整验证身份证号 Args: id_card: 身份证号 Returns: (是否有效, 错误信息) """ # 转大写 id_card = id_card.upper().strip() # 格式验证 valid, error = cls.validate_format(id_card) if not valid: return False, error # 出生日期验证 valid, error = cls.validate_birth_date(id_card) if not valid: return False, error # 校验码验证 valid, error = cls.validate_check_code(id_card) if not valid: return False, error return True, "" def validate_real_name(name: str) -> tuple[bool, str]: """ 验证真实姓名 Args: name: 姓名 Returns: (是否有效, 错误信息) """ # 去除首尾空格 name = name.strip() # 长度验证(2-20位) if len(name) < 2 or len(name) > 20: return False, "姓名长度应为2-20个字符" # 纯汉字验证(不允许特殊符号、空格) if not re.match(r'^[\u4e00-\u9fa5]+$', name): return False, "姓名只能包含汉字,不能有空格或特殊符号" return True, ""