Python身份证脱敏案例如何隐藏证件号

wen python案例 20

Python身份证脱敏案例:如何隐藏证件号?超详细操作指南

📚 目录导读


为什么要做身份证脱敏?

在数据处理、日志输出、接口返回等场景中,身份证号属于敏感个人信息,根据《个人信息保护法》,企业必须对敏感数据进行脱敏处理,否则可能面临法律风险。

Python身份证脱敏案例如何隐藏证件号

核心需求:将完整的18位身份证号码(如110101199001011234)转换成保留部分信息的模糊形式(如110101******1234),既满足业务需要,又能保护用户隐私。


常见的身份证脱敏规则

规则类型 脱敏方式 示例
保留前6后4 显示前6位(地址码)+ 后4位(顺序码校验码),中间8位隐藏 110101 ****** 1234
保留前6后3 显示前6位+后3位,中间9位隐藏 110101 ********* 234
保留前2后2 只显示前2位省份码+后2位,中间14位隐藏 11**** **** **** 34
全部隐藏 完全不显示身份证号

业务推荐:大多数场景使用保留前6后4规则,因为前6位可以区分地区,后4位用于确认用户身份,中间8位(出生日期+顺序码)严格隐藏。


Python实现身份证脱敏的5种方案

这里整理了5种从简单到复杂的实现方式,你可以根据项目场景选择。

方案1:字符串切片替换(最基础)

def mask_id_card_v1(id_card):
    return id_card[:6] + "********" + id_card[-4:]

方案2:正则表达式替换

import re
def mask_id_card_v2(id_card):
    return re.sub(r'(?<=\d{6})\d{8}(?=\d{4})', '********', id_card)

方案3:使用format格式化

def mask_id_card_v3(id_card):
    return "{}********{}".format(id_card[:6], id_card[-4:])

方案4:支持自定义脱敏长度

def mask_id_card_v4(id_card, front=6, end=4, mask_char='*'):
    mask_len = len(id_card) - front - end
    return id_card[:front] + mask_char * mask_len + id_card[-end:]

方案5:批量脱敏(pandas适用)

import pandas as pd
def mask_id_card_v5(df, column_name):
    df[column_name] = df[column_name].apply(lambda x: x[:6] + '********' + x[-4:])
    return df

完整代码实战案例

下面是一个完整的Python脚本示例,包含数据生成、脱敏、验证和导出功能。

import pandas as pd
import random
import re
# 1. 生成模拟身份证数据
def generate_fake_id_card():
    """生成一个假的身份证号(仅用于演示)"""
    area_code = "110101"
    birth = "19900101"
    seq = str(random.randint(100, 999))
    # 校验码简单生成(正式校验需ISO 7064:1983)
    check = "X" if random.random() > 0.9 else str(random.randint(0, 9))
    return area_code + birth + seq + check
# 2. 脱敏函数(推荐方案)
def mask_id_card(id_card):
    """仅保留前6位和后4位,中间用*替换"""
    if len(id_card) != 18:
        return id_card  # 非18位不处理
    return id_card[:6] + "********" + id_card[-4:]
# 3. 批量处理+导出
data = {
    "user_id": [1, 2, 3, 4, 5],
    "name": ["张三", "李四", "王五", "赵六", "钱七"],
    "id_card": [generate_fake_id_card() for _ in range(5)]
}
df = pd.DataFrame(data)
# 应用脱敏
df["id_card_masked"] = df["id_card"].apply(mask_id_card)
print("原始数据:")
print(df[["name", "id_card"]])
print("\n脱敏后的数据:")
print(df[["name", "id_card_masked"]])
# 4. 导出为CSV
df.to_csv("masked_data.csv", index=False, encoding="utf-8-sig")

输出示例: | name | id_card_masked | |------|----------------| | 张三 | 1101011234 | | 李四 | 1101015678 |


脱敏后的数据验证与注意事项

✅ 验证要点

  1. 长度校验:脱敏后字符串长度必须与原身份证号一致(18位)
  2. 格式保留:前6位和后4位必须是数字,中间8位是
  3. 可逆性:脱敏数据应不可逆,不能通过算法恢复原始数据

⚠️ 注意事项

  • 国际化公民号:如果处理港澳台、外籍人士证件,长度和格式不同,需单独处理
  • 日志脱敏:在打印日志时,建议使用logging模块配合自定义Filter实现自动脱敏
  • 数据库层面:可以使用MySQL的INSERT()函数或SQL Server的STUFF()函数在查询时脱敏

Q&A常见问题

Q1:脱敏后的身份证还能查到具体出生日期吗?

:不能,采用保留前6后4规则后,隐藏的是第7-14位(出生日期),用户无法从脱敏数据推断具体生日。

Q2:为什么不用替换整个字符串?

:保留前6位可以区分地区,后4位用于数据比对(如确认该用户是否存在),全隐藏会导致业务无法正常使用。

Q3:如果身份证号是15位(旧版)怎么办?

:可在代码增加分支判断:

if len(id_card) == 15:
    return id_card[:6] + "*****" + id_card[-4:]
elif len(id_card) == 18:
    return id_card[:6] + "********" + id_card[-4:]

Q4:脱敏后还能用于匹配数据库吗?

:建议在数据库层保存原始加密数据(如AES加密),对外接口返回脱敏数据,业务匹配应通过加密后的hash值进行,而非脱敏字符串。

Q5:有没有一键脱敏的Python库推荐?

:推荐使用presidio-anonymizer(微软开源)或faker(生成脱敏数据),但若只需简单规则,自己写函数更轻量。


身份证脱敏是数据安全的必备技能,在Python中,通过字符串切片结合替换是最常用且可靠的方法,建议始终保留前6位和后4位,其他位置隐藏,以保证业务可识别性,如果需要进一步处理大量数据,可以结合pandas进行批量操作。

抱歉,评论功能暂时关闭!