tm-desensitize/tmkit/README.md

55 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 |
## 用法示例
```python
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)
```
自定义规则:
```python
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