[安全开发]日志敏感信息检测-2-银行卡

  1. 前言
  2. 银行卡号码格式
  3. 正则提取
  4. 卡bin校验
  5. 校验码校验
  6. 优化思考

前言

接上一篇文章:[安全开发]日志敏感信息检测-1-身份证

银行卡号码格式

银行卡号码由14至19位数字组成,储蓄卡一般是19位、17位和16位,信用卡一般是16位,其中:

  • 前n位:发卡行识别码,用来标识哪个银行发行的卡,在本文中统一简称为“卡bin”
  • 中间位:个人账户标识,由发卡行自己定义,最多12位
  • 末位:校验码,由前面的数字采用Luhn算法计算得出

正则提取

首先通过正则,进行简单的筛选,从日志中提取疑似银行卡号码的数字。

\W\d{14,19}\W

正则说明

  • \W:匹配非单词字符,与"[^A-Za-z0-9_]"等效
  • \d{14,19}:匹配14至19位数字

宽进:在上面的正则表达式里,我们用了十分宽松的正则来匹配银行卡号码,只要是14至19位的数字,就都匹配上,这样能保证所有疑似银行卡号码的数字都被找出来。
严出:通过上面正则命中的数字误报会很多,但没关系,再对这些数字进行银行码和校验码校验,能过滤掉绝大部分误报,筛选出真正的银行卡号码。

卡bin校验

银行卡卡bin的长度不固定,一般是6位,但也有短至2位,长至12位的。
我们可以将正则命中的数字,从卡bin长度、卡bin值、银行卡长度三个维度,与卡bin库进行对比,三个值都符合的情况下,最后进行校验码的校验。
银行卡卡bin库搬运:银行卡卡bin数据
银行卡卡bin样例

校验码校验

前面说了,银行卡最后一位是校验码,由银行卡最后一位前面的所有数字计算得到,具体的计算算法这里不深究,感兴趣的读者,可以参考这篇博客:银行卡号的编码规则及校验
这里我们直接给出,银行卡校验码的校验算法的Java代码实现:

/**
 * 银行卡校验码Luhm校验算法,校验成功则为银行卡卡号
 *
 * @param bankCardNo 银行卡号码
 * @return true-校验成功;false-校验失败
 */
public static boolean bankCardNoCheck(String bankCardNo) {
    String num = bankCardNo.substring(0, bankCardNo.length() - 1);
    char[] numArray = num.toCharArray();
    int luhmSum = 0;
    for (int i = numArray.length - 1, j = 0; i >= 0; i--, j++) {
        int k = numArray[i] - '0';
        if (j % 2 == 0) {
            k *= 2;
            k = k / 10 + k % 10;
        }
        luhmSum += k;
    }
    char checkNo = (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    return bankCardNo.charAt(bankCardNo.length() - 1) == checkNo;
}

优化思考

通过上面的 正则提取+卡bin校验+校验码校验 三部曲,从日志中检测出的数字,基本99%是银行卡号码,准确率极高。但在海量日志的检测过程中,各种奇葩数据都有,还是会存在1%的误报的。

对于这1%的误报,有两个处理思路:

  1. 误报为偶然出现,且只出现过一两次,也没有其他类似特征的误报,则直接忽略即可
  2. 误报具有一定的特征,且多次出现,为同一类误报,则可以提取特征,针对性的制定白名单过滤。白名单推荐采用正则匹配进行过滤
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值