The Veil of Hidden Names — Helan
简体中文 · English
展示名 The Veil of Hidden Names 意为“隐名之幕”;Helan 是该项目的短名。
中文优先的 PII 检测与脱敏库。校验和级识别,可逆 Vault 还原,格式保留假名——帮助你在把数据交给大模型或其他服务前发现并处理敏感信息。
为什么需要它 / Why
在将中文业务文本送入 LLM、RAG 或其他外部处理服务前,开发者常需要识别并处理个人信息。通用识别框架可扩展,但中文证件校验、误报控制和可恢复脱敏通常需要额外规则与评测。
helan(Helan)把这件事做成零依赖标准件:
- 格式校验:对身份证、银行卡和统一社会信用代码应用相应校验规则,减少仅凭位数与字符模式产生的误报;其他实体依赖上下文规则,仍可能漏检或误报
- 偏移不变量:每个实体保证
entity.text == source[start:end](fuzz 测试永久守护),脱敏结果可精确引用回原文 - 可逆 Vault:用占位符脱敏并通过受保护的 Vault 还原;Vault 含有恢复敏感信息,必须与原文同等保护
- 格式保留假名:
fake算子生成的假身份证能通过身份证校验、假银行卡能通过 Luhn——替换后的数据仍是"合法格式",适合造测试集与演示数据 - 零必装依赖:核心纯 Python;jieba(人名 NER 补召回)与 LLM(语义级兜底)全部可选
- 自带评测:内置 12 篇中文语料 + P/R/F1 报告,数字如实
安装 / Install
python -m pip install helan
python -m pip install "helan[jieba]" # 可选增强,按需安装
从源码安装(开发或最新版):
git clone https://github.com/cloudydreamland/TheVeilOfHiddenNames.git
cd TheVeilOfHiddenNames
python -m pip install .
快速开始 / Quickstart
from helan import mask, restore, recognize
text = "出租方张伟明(身份证 11010519491231002X,电话 13812345678)同意将房屋出租。"
# 只识别
for e in recognize(text):
print(e.type, e.start, e.end, e.text)
# 可逆脱敏:只处理身份证,占位符可精确还原
# (types 限定识别范围;不传 types 时所有类型按默认算子脱敏)
masked, vault = mask(text, ops={"ID_CARD": "vault"}, types=["ID_CARD"])
original = restore(masked, vault)
assert original == text
# 不可逆脱敏:手机号换成"合法格式"的假号码
masked, _ = mask(text, ops={"PHONE": "fake"})
命令行:
helan scan 合同.txt --json # 只识别
helan mask 合同.txt -o 脱敏.txt --ops ID_CARD:vault,PHONE:fake --vault-out vault.json
helan restore 脱敏.txt --vault vault.json -o 还原.txt
helan eval # 内置基准报告
实体类型与算子
| 类型 | 识别方式 | 默认算子 |
|---|---|---|
| ID_CARD 身份证 | 区划+出生日期+MOD 11-2 校验码 | partial(前3后4) |
| BANK_CARD 银行卡 | Luhn 校验(支持空格/连字符分组) | partial(留后4) |
| USCC 统一社会信用代码 | GB 32100 MOD 31-3 校验 | partial |
| PHONE 手机号 | 号段表严格校验 | partial(138****5678) |
| PERSON_NAME 人名 | 称谓/引导词/顿号枚举上下文;jieba nr 可选 | partial(张**) |
| ADDRESS 地址 | 引导词上下文 | redact |
| LANDLINE / EMAIL / IP / URL / PASSPORT / LICENSE_PLATE | 规则+守卫 | partial/redact |
| TW_ID_CARD 台湾身份证 | 地区字母码+性别位+加权 MOD 10 校验 | partial |
| POSTAL_CODE / QQ / 微信号 / OFFICER_ID | 关键词上下文(军官证为 format-only,如实标注) | redact/partial |
| ID_CARD 全角/符号分隔写法 | 1101 0519 4912 3100 2X 等分隔归一化后过校验和 | partial |
算子:redact(标签替换)/ partial(部分保留)/ hash(加盐稳定假名)/ fake(合法格式假数据)/ vault(可逆占位)/ 任意自定义 callable。
与现有方案的关系 / Landscape
我们曾用固定版本的 presidio-analyzer 与本项目内置语料做对照。测试范围、配置、语料及局限见方法和完整结果;这些结果只适用于该次设置,不代表所有 Presidio 中文部署:
| 方案 | 实测/事实 |
|---|---|
| Presidio 等通用框架 | 提供可配置的识别与匿名化管线;中文效果取决于所选 recognizer、规则和评测语料 |
| 自定义正则 | 易于嵌入,但需要自行实现格式校验、上下文规则、偏移处理和评测 |
| Helan | 聚焦中文规则、原文偏移以及多种脱敏算子;适用范围和评测边界见下文 |
选题取证(为什么这个缺口是真的)见 GAP_PROOF.md。
评测 / Evaluation
内置基准(14 篇中文合成文档(含散文体)/ 48 个 gold 实体)真实结果:benchmarks/results.md
- 当前快照:default 配置 P 1.000 / R 1.000 / F1 1.000;无上下文配置 R 0.644(人名/地址全靠上下文层)
- 诚实声明:语料为合成文档(由本库假数据生成器构造,标注零噪声),分布窄于真实业务文档,数字代表格式级能力上限,不外推为生产效果
性能 / Performance
2MB 混合文本、单核(benchmarks/perf.md):完整管线 2.35 MB/s(3.4 万实体),比"同正则、零校验"的手搓基线慢 2.8 倍——这个代价买的是误报治理。
从 presidio 迁移 / Migration
from helan.compat_presidio import MianjuAnalyzer
results = MianjuAnalyzer().analyze(text="证件号 23144319731204692X", entities=["ID_CARD"])
for r in results:
print(r.entity_type, r.start, r.end, r.score) # 属性面与 presidio 一致
大文本 / Streaming
from helan import recognize_iter, read_file_chunks
for e in recognize_iter(read_file_chunks("huge.txt"), chunk_size=65536, overlap=512):
print(e.type, e.start, e.end, e.text) # 返回绝对偏移;该测试样本与整读结果一致,详见性能报告
约束:单实体长度须小于 overlap(URL 已加 512 上限与之匹配)。
路线图 / Roadmap
见 ROADMAP.md。当前 v0.1.0:17 类型识别(含台湾身份证校验和、全角分隔身份证写法)+ 4 类算子 + Vault 还原 + 内置评测 + 流式 API + 黑名单校准,194 项测试全绿。
Metadata
Release files for helan 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| helan-0.1.0.tar.gz | 57.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| helan-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 108.5 kB
Release files / helan-0.1.0.tar.gz
| Download URL | helan-0.1.0.tar.gz |
|---|---|
| Size | 57.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cef8ee1aec9b39e1d8db4da775e30e9fd98004ea96401a4e69d26cf86916c86d
|
|
BLAKE2b-256 checksum How to use checksums |
5b30370dda00bbf0c319cf02d6cd68afd8c5d340eec5c967384cfd5973456be5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency logRelease files / helan-0.1.0-py3-none-any.whl
| Download URL | helan-0.1.0-py3-none-any.whl |
|---|---|
| Size | 51.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
94243b5779982a1050cea0b7e8e780dd281172d79f34365c765fd764602b6494
|
|
BLAKE2b-256 checksum How to use checksums |
8ba7623aa6e131916a62562e531dfdc3788ed8c659ae1983abcfe0e500d105bd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency log