更新记录
1.0.0(2026-10-29)
首个版本:识别 9 类敏感信息(手机号、身份证 18/15 位、银行卡 Luhn、统一社会信用代码 GB 32100、邮箱、中文姓名上下文、地址、IPv4、车牌),校验位先算后判并把不通过的标 valid=false;三档分级打码(L1 客服展示 / L2 日志埋点 / L3 对外导出),每档 9 类规则可查、可按类型只处理指定项,L3 身份证换 FNV-1a 关联标记、部分类型用定长星号避免反推长度;整段 / 逐行 CSV 保留表头 / 整文件三种入口,原文不动结果另存;重叠命中保留风险更高者;命中清单带位置、校验状态与判定依据。CSV 表头语义识别:列名对应类型时按该类型打码,字段数与表头不符则退回整行识别。UTS→Kotlin 编译通过(index.kt 1992 行、103 个函数,生成 classes.dex 68,520 字节),76 项回归测试全部通过;真机未执行(本轮无可用设备)。
平台兼容性
uni-app
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | × | × | √ | × | √ | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | - | × | × | - | × | × |
szhzy-mask-guard
把工单、日志、导出文件里的敏感信息按类型认出来,再按档位打码。 识别 9 类,三档分级,整段 / 逐行 / 整文件都能处理。纯本地计算,不联网、不上传、不写日志。
适用场景:客服工单截图前脱敏、前端埋点日志落地前脱敏、对账明细导给第三方前脱敏、隐私合规自查。
验证状态
| 项 | 结果 |
|---|---|
| UTS → Kotlin 编译 | 通过(编译成功,无 error;index.kt 1992 行 / 103 个函数,生成 classes.dex 68,520 字节) |
| 纯逻辑回归测试 | 76 项,失败 0(dev-tools-uts/verify/mask-guard/run-tests.mjs) |
| 真机运行 | 未执行(本轮无可用设备,adb devices 为空) |
| iOS / 鸿蒙 | 不支持,仅 Android |
真机未验证的部分:Android 平台层的文本文件读取、
content://授权 URI 转缓存、写出目录。 接入前请在自己的设备上先跑一遍「选文件 → 打码 → 写出」。 纯逻辑部分(识别、校验位、分档规则、打码、关联标记)已全部在 Node 下真实执行。
它不做什么
- 不保证 100% 召回。识别靠规则 + 校验位,不靠模型。姓名、地址这类弱特征字段误漏都可能发生,涉及强合规场景请人工复核。
- 不做格式保留。docx / pdf / xlsx 的内部结构不解析,只处理纯文本与 CSV 文本。Excel 请先导出成 CSV。
- 不还原原文。打码是不可逆的(L3 的关联标记也只是摘要,不可反推)。
- 不做加密。要加密存储请用专门的加密方案,本插件只负责「遮住」。
- 不管图片与人脸。截图里的手机号识别不出来。
快速开始
import { maskTextApi, detectText, maskLinesApi, maskFile } from '@/uni_modules/szhzy-mask-guard'
// 1) 先看这段文字里有什么敏感信息(不改写)
const found = detectText({ text: ticket })
if (found.ok) {
console.log(found.count, found.risk) // 命中数、最高风险等级 1/2/3
found.hits.forEach((h) => console.log(h.type, h.value, h.valid, h.reason))
}
// 2) 按 L2(日志埋点)打码
const out = maskTextApi({ text: ticket, level: 2 })
console.log(out.text) // 已打码文本
// 3) CSV 逐行打码,保留表头
const csv = maskLinesApi({ text: csvText, level: 2, keepHeader: true })
console.log(csv.text)
// 4) 整个文件处理,原文不动,结果另存
const file = maskFile({
path: filePath, // 系统选择器给的路径或 content:// 授权 URI
level: 3,
fileName: '对账明细-脱敏',
keepHeader: true
})
console.log(file.ok, file.path, file.masked)
同一段文字在三档下的实际输出(maskTextApi 的返回值去掉未变部分):
原文:联系人:张伟,手机 ***,统一社会信用代码 91440300MA5DB1XY3B
L1:联系人:张*,手机 138****8000,统一社会信用代码 9144**********XY3B
L2:联系人:张*,手机 138******00,统一社会信用代码 91**************3B
L3:联系人:*,手机 138****,统一社会信用代码 91****
L3 的身份证不是打星号,而是换成关联标记,同一号码每次输出一样、不同号码不一样,便于跨日志比对又不泄露原文:
11010519491231002X → #c50ffac5
API
所有方法返回统一信封 { ok, code, message, ... },不抛异常。
| 方法 | 入参 | 返回要点 |
|---|---|---|
detectText |
{ text, types? } |
hits[]、count、risk(只识别不改写) |
maskTextApi |
{ text, level=2, types?, char='*' } |
text、masked、risk、hits[]、counts[]、lines |
maskLinesApi |
{ text, level=2, keepHeader=true, types?, char='*' } |
同上,逐行处理,可保留首行表头 |
maskFile |
{ path, level=2, keepHeader=false, byLine=true, dir?, fileName?, bom=true, types?, char? } |
同上 + path(新文件路径)、fileName、bytes |
verifyCode |
{ kind: 'idcard'\|'bank'\|'uscc', value } |
valid、digits,用于录入时就地校验 |
fingerprint |
{ value } |
digest(8 位十六进制关联标记) |
policyOfLevel |
{ level } |
rules[]:该档每类保留前几位、后几位 |
policyMatrix |
— | 三档规则一次性取出,做对照表用 |
types |
— | 支持的 9 类清单,含 risk 与 how(识别依据) |
getOutputDir |
— | 默认输出目录(应用外部私有目录) |
getVersion |
— | 插件版本 |
命中项字段
| 字段 | 说明 |
|---|---|
type |
phone / idcard / bank / uscc / email / name / address / ip / plate |
title |
中文名,直接可上屏 |
value |
命中的原始片段 |
start / end |
在原文中的位置,可用来做高亮 |
valid |
校验位是否通过(仅 idcard / bank / uscc 有意义);false 表示原数据本身可能是脏的 |
risk |
1 低 / 2 中 / 3 高 |
reason |
判定依据,如「11 位号码,1 开头且第二位 3-9」 |
三档分级
| 档位 | 用途 | 手机号 | 身份证 | 银行卡 | 姓名 |
|---|---|---|---|---|---|
| L1 | 客服展示(能核对身份) | 留 3+4 | 留 6+2 | 留 4+4 | 留姓 |
| L2 | 日志埋点(默认) | 留 3+2 | 留 3+1 | 留 4+2 | 留姓 |
| L3 | 对外导出(最严) | 留 3 + 定长 4 星 | 关联标记 | 留 4 + 定长 4 星 | 全遮 |
fixed 项用定长星号替代变长数字,避免从星号个数反推出原文长度。
单类型覆盖:传 types: ['phone', 'idcard'] 就只处理这两类,其余原样保留。
识别依据
| 类型 | 怎么认 |
|---|---|
| 手机号 | 11 位、1 开头、第二位 3-9;兼容 +86 / 86 前缀与空格、连字符分隔 |
| 身份证 | 18 位加权模 11 校验;15 位老号按长度识别 |
| 银行卡 | 16-19 位,Luhn 校验;不通过的仍按卡号打码并标 valid=false |
| 统一社会信用代码 | 18 位 GB 32100 加权模 31 校验,须含字母 |
| 邮箱 | @ 前后按字符集回溯,域名须带点且顶级域 ≥2 位 |
| 中文姓名 | 紧跟「姓名/联系人/收货人/申请人/负责人/经办人/签收人/业务员/开票人」等关键词,且首字为常见姓氏 |
| 地址 | 省级行政区名开头,尾部出现路/街/号/村/镇/区/县等门牌特征 |
| IPv4 | 四段 0-255 |
| 车牌 | 省份简称 + 发牌机关字母 + 5 位号牌 |
重叠处理:同一位置命中多类时保留风险更高的那个(身份证优先于银行卡,因为 18 位数字两者都像)。
错误码
| code | 含义 | 处理建议 |
|---|---|---|
EMPTY |
入参为空 | 检查 text / path / value 是否传了 |
KIND_UNKNOWN |
verifyCode 的 kind 不在三选一里 |
只能是 idcard / bank / uscc |
READ_FAILED |
文件读不出来 | content:// 授权可能已失效,重新选择 |
WRITE_FAILED |
写文件失败 | 检查 dir 是否可写 |
FILE_NOT_FOUND |
文件不存在 | 确认选择器返回的路径有效 |
演示工程
demo-mask-guard/ 两个页面:
- 工单脱敏:一段客服工单文本,切换 L1/L2/L3 看打码结果差异,下方命中清单带风险徽章与校验状态,再下面是三档保留位对照表;
- 批量脱敏:CSV 明细表处理前/后对照,展示逐行打码 + 保留表头,末尾是处理说明与写出结果卡。
预览环境(H5)用固定样本数据走通页面流程,结果卡会标注「预览环境」;装到 Android 后同一次操作走的是真实插件。
隐私说明
- 不联网、不上传、不写日志、不采集统计。
- 待处理文本只在内存中,处理完随调用返回,插件不自行缓存。
- 输出文件默认写应用外部私有目录(
getExternalFilesDir),不需要存储权限。 - 关联标记是 FNV-1a 32 位摘要,不是加密,不要当密码学哈希用。
授权
购买授权后可在自己的产品(含为客户定制的项目)中不限项目数、不限安装量使用。
源码授权另允许阅读与二次开发,但不得把插件本身(含修改版)再次分发或销售。详见 license.md。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 13
赞赏 0
下载 12723595
赞赏 1958
赞赏
京公网安备:11010802035340号