macshot PII自动脱敏实现原理从正则模式到Vision OCR与PIIRedactionPlanner【免费下载链接】macshotFeature-packed native macOS screenshot recording tool: annotate, auto-redact PII, record GIFs, OCR translate, scroll capture, beautify, and more. No Electron, no subscription.项目地址: https://gitcode.com/gh_mirrors/mac/macshotmacshot 是一款纯原生 macOS 截图与录屏工具其中的PII 自动脱敏自动打码个人敏感信息功能尤为实用框选截图区域后它会自动找出卡号、邮箱、密钥等敏感内容并盖上马赛克。本文带你完整拆解它的实现原理——从正则模式匹配到 Vision OCR 识别再到 PIIRedactionPlanner 决策层看看这套不会漏打码的隐私保护机制是如何设计的。一键自动脱敏先看看最终效果 ️在实际使用中如上图当你选中截图区域并点击 PII 按钮时画面中的卡号、CVV、过期日期等会被自动像素化处理底部菜单还能切换脱敏方式Pixelate/Blur/Solid/Erase并勾选要识别的类型Emails、Phone Numbers、SSN、Credit Cards、CVV、IP Addresses、AWS Keys、Secrets/Tokens、Hex Keys、Bearer Tokens共 12 类。这一切的入口在 ToolOptionsRowView.swift 的redactPIIClicked()最终调用 AutoRedactor.swift 的redactPII()。第一层防线12 种敏感信息正则模式脱敏的规则库集中在 AutoRedactor.swift 的sensitivePatterns中每条模式由类型名 正则组成统一忽略大小写类型能识别什么email邮箱地址如janeexample.comphone电话号码含 1 前缀、括号区号ssn社保号123-45-6789credit_card多组 4 位数字分组的卡号含 OCR 少识别一位的残缺卡号cvvCVV: 123这类带标签的校验码expiry12/26形式的过期日期ipv4IPv4 地址aws_keyAKIA/ASIA开头的 AWS 密钥secret_assignmentpassword、api_key:等密钥赋值语句hex_key32 位以上的十六进制长串bearerBearer xxx授权令牌其中卡号的第三条模式\d{4,6}(?:\s\d{4,6}){2,4}值得注意源码注释解释了它为什么要求至少三个数字组——否则 2026 2026、1024 768 这类普通内容会被误判成卡号反而盖住用户想展示的内容。匹配逻辑由sensitiveMatches(in:enabledTypes:)完成OCR 交付一行文本正则返回所有命中区间且只处理用户在设置里勾选启用的类型enabledRedactTypes被禁用的类型绝不脱敏。用 Vision OCR 让机器读截图正则只能匹配文本而截图是图片中间靠 VisionOCR.swift 这座桥精准优先默认使用accurate识别级别并在 macOS 13 开启automaticallyDetectsLanguage自动检测语言、usesLanguageCorrection语言纠错失败降级如果平台模型失败自动以fast级别重试一次保证功能可用性坐标对齐每个VNRecognizedTextObservation都携带 bounding box为后续把哪一块盖住提供精确位置。redactPII()的整体流程是裁剪选区 → 后台线程跑 OCR → 交给决策层 → 主线程生成打码标注见 AutoRedactor.swift。PIIRedactionPlannerOCR 之后的决策引擎OCR 结果并不完美一行卡号可能被拆成多个文本块、OCR 会丢字符、普通数字也会大量出现。这些脏的判断全部被剥离到一个与 Vision、绘图无关的纯决策层 PIIRedactionPlanner.swift 中核心是matches(in:enabledTypes:)三步逐行正则 区间去重对每行 OCR 文本跑一遍sensitiveMatches。若同一类型多个模式命中同一区间卡号恰好有三条模式只保留最宽的那个区间避免同一处叠加多个打码框。跨块拼接还原被 Vision 拆散的卡号这是整个设计里最精巧的部分。卡号4111 1111 1111 1111在 OCR 眼中可能是四个独立的文本块。决策层会按midY把数字块归入同一文本行重叠度 ≥ 60% 且高度接近才视为同排沿 X 轴按左到右排列当相邻块间距超过两倍的行高时切成独立连续段——因此相隔很远的两列数字不会拼成假卡号把段内文本用空格拼接后再次跑卡号正则要求数字组 ≥ 3 组、总位数落在 12–19 位之间才判定为真卡号并把命中区间映射回各原始文本块分别打码。CVV 上下文推断单独一个 123 无法被正则认定为 CVV。决策层会寻找上下文锚点行内带有CVV/CVC/CSC/CCV标签或附近存在已识别的卡号。附近由nearby()判定——同一文本行内横向间距 ≤ 3 倍文字高度或垂直相邻且水平重叠且间距 ≤ 2 倍文字高度。注意这里以文字高度为比例尺而非截图尺寸的固定比例因此对任意裁剪形状都成立。更微妙的是如果你只勾选了 CVV 类型卡号上下文可以帮它找到校验码却不会顺带把卡号本身也打码——类型选择被严格遵守。从匹配结果到打码框生成脱敏标注决策层返回的每个Match行索引 类型 文本区间会被换算成像素坐标优先调用candidate.boundingBox(for:)精确到子串位置若 Vision 给不出子串框则宁宽勿漏——直接覆盖整行已识别文本确保检测到的敏感内容绝不被悄悄漏掉AutoRedactor.swift。生成的 Annotation 会按用户设置的censorMode马赛克/模糊/纯色/擦除烘焙像素并共享同一个groupID这样 CmdZ 撤销时整批脱敏框一次撤干净。同一套管线也服务于 All Text打码全部文字与人脸/人体检测脱敏后者复用 Vision 的VNDetectFaceRectanglesRequest等请求坐标换算逻辑完全一致。测试护航为什么漏打码是零容忍的 ️隐私功能最怕的不是多盖一个框误报而是该盖的没盖漏报——用户会带着没打码的密钥就发出去了。测试套件把这一点写进了注释AutoRedactorPatternTests.swift正则层覆盖各类正常格式命中、边界内容不误报如#a1b2c3这种短 hex 不当密钥、每种设置里宣传的类型都真实可匹配甚至还有两万字超长行不卡死的回溯性能测试决策层PIIRedactionPlannerTests.swift 用公开的测试卡号模拟不均匀 OCR 拆分、远距离数字列不组卡、CVV 不误伤卡号、Unicode阿拉伯数字区间、NaN/零尺寸等无效 OCR 框不产生非法标注等场景并验证只勾卡号时不会连带打码 CVV 与过期日期这类类型隔离语义。总结macshot 的 PII 自动脱敏把复杂度分层处理得很干净规则层AutoRedactor.swift——12 类正则 用户可勾选的启停控制识别层VisionOCR.swift——精准 OCR 失败降级 子串坐标决策层PIIRedactionPlanner.swift——去重、跨块拼卡号、CVV 上下文推断以文字高度为比例尺的几何判断呈现层Annotation.swift——四种打码模式、批量撤销。对普通用户来说只需选区 一键 PII对开发者来说这套宁宽勿漏 严格尊重类型选择 测试兜底的设计是处理 OCR 脏数据时非常值得借鉴的工程范例。【免费下载链接】macshotFeature-packed native macOS screenshot recording tool: annotate, auto-redact PII, record GIFs, OCR translate, scroll capture, beautify, and more. No Electron, no subscription.项目地址: https://gitcode.com/gh_mirrors/mac/macshot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考