一个非常不错的验证身份证号码的函数

一个非常不错的验证身份证号码的函数

环境

python 3

具体代码

基础版

def validate_idcard(idcard):
    # 1. 基础格式校验
    if len(idcard) != 18:
        return False, "长度错误"

    # 正则匹配(允许最后一位为X/x)
    pattern = r'^\d{17}[\dXx]$'
    if not re.match(pattern, idcard):
        return False, "格式错误"

    # 2. 出生日期校验
    try:
        birth_date = datetime.strptime(idcard[6:14], "%Y%m%d")
        if birth_date > datetime.now():  # 排除未来日期
            return False, "出生日期在未来"
    except ValueError:
        return False, "无效出生日期"

    # 3. 校验码计算
    weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
    check_codes = "10X98765432"

    total = sum(int(idcard[i]) * weights[i] for i in range(17))
    expected_check = check_codes[total % 11]

    if idcard[-1].upper() != expected_check:
        return False, f"校验码错误(应为{expected_check})"

    return True, "有效身份证号"

错误定位增强版

def detailed_validate(idcard):
    errors = []

    # 长度校验
    if len(idcard) != 18:
        errors.append("长度必须为18位")

    # 格式校验
    if not re.match(r'^\d{17}[\dXx]$', idcard):
        errors.append("包含非法字符(仅允许数字和末位X/x)")

    # 地区码校验(需扩展地区码库)
    # area_code = idcard[:6]
    # if area_code not in valid_area_codes:
    #     errors.append("无效地区编码")

    # 出生日期校验
    try:
        birth_date = datetime.strptime(idcard[6:14], "%Y%m%d")
        if birth_date > datetime.now():
            errors.append("出生日期在未来")
    except ValueError:
        errors.append("出生日期格式错误(应为YYYYMMDD)")

    # 校验码校验
    weights = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
    check_codes = "10X98765432"
    total = sum(int(idcard[i])*weights[i] for i in range(17))
    expected = check_codes[total%11]

    if idcard[-1].upper() != expected:
        errors.append(f"校验码错误(应为{expected},实际为{[1](@ref)})")

    return len(errors) == 0, errors

性能优化版(批量处理)

def detailed_validate(idcard):
    errors = []

    # 长度校验
    if len(idcard) != 18:
        errors.append("长度必须为18位")

    # 格式校验
    if not re.match(r'^\d{17}[\dXx]$', idcard):
        errors.append("包含非法字符(仅允许数字和末位X/x)")

    # 地区码校验(需扩展地区码库)
    # area_code = idcard[:6]
    # if area_code not in valid_area_codes:
    #     errors.append("无效地区编码")

    # 出生日期校验
    try:
        birth_date = datetime.strptime(idcard[6:14], "%Y%m%d")
        if birth_date > datetime.now():
            errors.append("出生日期在未来")
    except ValueError:
        errors.append("出生日期格式错误(应为YYYYMMDD)")

    # 校验码校验
    weights = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
    check_codes = "10X98765432"
    total = sum(int(idcard[i])*weights[i] for i in range(17))
    expected = check_codes[total%11]

    if idcard[-1].upper() != expected:
        errors.append(f"校验码错误(应为{expected},实际为{[1](@ref)})")

    return len(errors) == 0, errors

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注