tm-desensitize/tmkit
2026-11-03 11:39:51 +08:00
..
tests tm脱敏系统 v0.1:分流+正则识别+坐标回写管线(12测试全绿) + FastAPI平台 + 进展看板 2026-11-03 11:39:51 +08:00
__init__.py tm脱敏系统 v0.1:分流+正则识别+坐标回写管线(12测试全绿) + FastAPI平台 + 进展看板 2026-11-03 11:39:51 +08:00
detector.py tm脱敏系统 v0.1:分流+正则识别+坐标回写管线(12测试全绿) + FastAPI平台 + 进展看板 2026-11-03 11:39:51 +08:00
extractor.py tm脱敏系统 v0.1:分流+正则识别+坐标回写管线(12测试全绿) + FastAPI平台 + 进展看板 2026-11-03 11:39:51 +08:00
README.md tm脱敏系统 v0.1:分流+正则识别+坐标回写管线(12测试全绿) + FastAPI平台 + 进展看板 2026-11-03 11:39:51 +08:00
redactor.py tm脱敏系统 v0.1:分流+正则识别+坐标回写管线(12测试全绿) + FastAPI平台 + 进展看板 2026-11-03 11:39:51 +08:00
splitter.py tm脱敏系统 v0.1:分流+正则识别+坐标回写管线(12测试全绿) + FastAPI平台 + 进展看板 2026-11-03 11:39:51 +08:00

tmkit — PDF 数据脱敏工具库(后端管线 · 最小可用版)

面向法律/金融文书 PDF 的 PII(个人敏感信息)自动脱敏。纯 Python 库,六大模块中的 4 个核心模块 + 测试 + 文档已交付。

模块

模块 功能
tmkit.splitter PDF 分流:get_text 检测文字层,逐页返回 native / scanned
tmkit.extractor 原生页按词抽取(get_text('words'),含 bbox 坐标);扫描页 raise NotImplementedError('OCR 待接入 PaddleOCR')
tmkit.detector PII 识别引擎:身份证 18 位(GB 11643 校验位)、大陆手机号、银行卡(Luhn)、统一社会信用代码(GB 32100)、邮箱;支持自定义规则注册
tmkit.redactor 坐标回写:add_redact_annot + apply_redactions(默认,删字最干净)或 draw_rect 黑条;输出脱敏后 PDF bytes

用法示例

import fitz
from tmkit import default_detector, extract_page_words, redact_pdf

pdf_bytes = open("input.pdf", "rb").read()
det = default_detector()
hits = []
with fitz.open(stream=pdf_bytes, filetype="pdf") as doc:
    for pno, page in enumerate(doc):
        hits += det.scan_page_words(extract_page_words(page), pno)
# hits: [{"type": "id_card", "text": "1101...", "page": 0, "bbox": (x0,y0,x1,y1)}, ...]

clean = redact_pdf(pdf_bytes, hits)          # method="redact"(默认,真删除)
open("output.pdf", "wb").write(clean)

自定义规则:

from tmkit import PIIDetector, Rule
import re
det = PIIDetector()
det.register(Rule("order_no", re.compile(r"(\d{4})京\d+民初\d+号")))

测试

cd tmkit && python3 -m pytest tests/ -v

样例 PDF 由 reportlab 在 conftest.py 中动态生成:纯文本页、身份证+手机号+银行卡+邮箱页、空白扫描页。断言覆盖:脱敏后 get_text 中 PII 不存在、非敏感文本保留、页数不变、黑块像素可见、校验算法正确性、无 PII 页零误报。

已知限制(下一步)

  • 扫描页 OCR(PaddleOCR)尚未接入,extractor 直接抛 NotImplementedError
  • PII 跨行换行(如身份证分两行)不会命中;词拼接按行内进行
  • method="draw" 只画黑条不删字,文本层仍可提取,仅作对比保留
  • 未处理旋转页 / 加密 PDF