从文本里扫卡号:信用卡号提取与卡号扫描的合规实战
讲清楚怎么从日志和导出文件里提取疑似信用卡号,用 13 到 19 位加 Luhn 校验筛出真卡号,做数据脱敏审计和合规扫描,全程浏览器本地处理不上传。
从文本里扫卡号:信用卡号提取与卡号扫描的合规实战
每个接过支付业务的团队迟早会遇到同一个尴尬:某天翻日志排错,发现一行请求体里赫然躺着一串完整卡号。它不该出现在那里,但它就是出现了。问题是,光这一行你看得到,几百兆的历史日志里还藏着多少?手工翻不现实,正则一把梭又会把订单号、手机号、时间戳全当成卡号。这篇文章讲的就是怎么把这件事做对。
什么样的数字串才算疑似卡号
判断一串数字是不是卡号,不能只看长度。业界通行的口径有两条同时成立才算数:
第一,长度落在 13 到 19 位之间。Visa 多为 16 位,American Express 是 15 位,部分早期卡和银联卡可能更短或更长,所以下限拉到 13,上限给到 19。
第二,通过 Luhn 校验。Luhn 算法是卡号尾位校验位的生成规则:从右往左数,把偶数位的数字乘 2(乘完超过 9 就减 9),再和奇数位相加,总和能被 10 整除才算合法。一个随手编的 16 位数字几乎不可能碰巧过 Luhn,所以这一步能把绝大多数误报挡在外面。
只有 13 到 19 位且过 Luhn 这两条都满足,才标记为疑似卡号。这是个刻意保守的口径:宁可漏掉个别非标准卡,也不要把一堆订单号误判成泄露,否则合规报告就成了狼来了。
一段日志扫出来是什么样
举个真实点的例子。假设你从网关日志里抓了这么几行:
2026-06-12 09:14:22 INFO order=88012391 user=4127 amount=129.00
2026-06-12 09:14:23 DEBUG payload={"pan":"4111111111111111","exp":"12/28"}
2026-06-12 09:14:25 INFO trace=378282246310005 retry=3
2026-06-12 09:14:26 INFO phone=13800138000 status=ok
把这四行粘进信用卡号提取器,它会输出一张带行号的审计表。第 2 行的 4111111111111111 是 16 位且过 Luhn,标记为疑似卡号有效;第 3 行那个 378282246310005 看着像 trace id,但它正好是 15 位 Amex 测试卡且过 Luhn,也会被挑出来,这恰恰是你想要的,因为它真的是卡号格式;而第 1 行的订单号 88012391 太短,第 4 行的手机号 13800138000 过不了 Luhn,两者都不会进有效命中。输出里命中的卡号会自动脱敏,你拿到的是位置和原因,而不是又一份明文卡号清单。
这就是工具的价值:它替你区分了"长得像数字"和"真的是卡号"。
为什么强调本地处理不上传
做卡号扫描这件事本身有个悖论:你扫描的是敏感数据,如果扫描过程要把日志发到某个在线服务,那等于又制造了一次泄露。所以这个工具把解析、Luhn 校验、去重、导出全部放在浏览器里跑,上传的本地文件走 File API 在当前标签页读取,不发往任何服务器。命中的卡号在结果里还会脱敏显示。
我自己在做一次季度自查时就是这么用的。手头是从测试环境导出的几个 csv 和一堆客服工单,总共两百多兆。我没敢把它们传到任何地方,直接拖进浏览器跑了一遍,十几秒就出来一张表,标出了三处历史遗留的明文卡号,每一处都带着行号,顺着行号回原文件定位,当天就提了整改单。整个过程数据没离开过我的机器,这对要写进合规记录的事来说很关键。
提取之后怎么配合脱敏和复核
扫出来只是第一步,后面通常还要做两件事:
一是规范化。从网页或 PDF 复制来的卡号常带着空格、连字符或隐藏空白,直接比对会漏。先用卡号规范化工具把它们统一成纯数字再去重,审计表才不会出现同一张卡占两行的情况。
二是留审计线索。不要只复制最终那串结果,把带行号的 CSV 或 Markdown 一起下载下来,整改时谁、哪一行、什么原因都查得到。需要进一步核对清单合法性时,还可以接卡号列表校验工具做二次确认。
几个容易踩的坑
最后提醒三点。其一,卡号过 Luhn 只说明格式合法,不代表这张卡真实存在或可用,别把校验当成真实性验证。其二,合规扫描的目标是发现泄露,不是收集卡号,所以一定要用脱敏输出,别图省事去看明文。其三,这类工具适合扫几兆到几十兆的文本,真要扫超大归档,先按时间或服务把相关文件抽出来,分批处理既快又稳。
把卡号扫描做成一个固定动作,排查日志、上线前自查、季度审计各跑一遍,泄露就很难悄悄溜过去。
Made by Toolora · Updated 2026-06-13