银行卡号合法性验证小结

关于银行卡号合法性的验证,网上主流的验证算法是luhn算法,代码如下:

[java]  view plain  copy
  1. /** 
  2.  * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位 
  3.  * @author mengrang 
  4.  * @since 2016/09/18 
  5.  */  
  6.    public static char getBankCardCheckCode(String nonCheckCodeCardId){      
  7.        if(nonCheckCodeCardId == null || nonCheckCodeCardId.trim().length() == 0      
  8.                || !nonCheckCodeCardId.matches("\\d+")||nonCheckCodeCardId.trim().length()<15    
  9.                ||nonCheckCodeCardId.trim().length()>18) {      
  10.            //如果传的数据不合法返回N      
  11.            return 'N';    
  12.        }      
  13.        char[] chs = nonCheckCodeCardId.trim().toCharArray();      
  14.        int luhmSum = 0;     
  15.        // 执行luh算法    
  16.        for(int i = chs.length - 1, j = 0; i >= 0; i--, j++) {      
  17.            int k = chs[i] - '0';      
  18.            if(j % 2 == 0) {  //偶数位处理    
  19.                k *= 2;      
  20.                k = k / 10 + k % 10;      
  21.            }      
  22.            luhmSum += k;                 
  23.        }      
  24.        return (luhmSum % 10 == 0) ? '0' : (char)((10 - luhmSum % 10) + '0');      
  25.    }  
银行卡号最后一位是校验位。

但是对于一些地方性的商业银行,该算法并不适用,实际应用中发现平安银行(原深圳发展银行16位借记卡)老卡没办法通过luhn算法。

无奈只能验证下银行卡Bin号的合法性,实际卡号的合法性移交给金融支付接口来判断,这一块没有算法支持。。。

网上最多验证Bin号的合法性最多的就是查表发,代码着实麻烦,所以网上各种查,最终发现了个良心接口,阿里提供的验证Bin号的免费接口:

https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=待验证银行卡号&cardBinCheck=true

返回json数据如下:

[javascript]  view plain  copy
  1. {"bank":"SPABANK","validated":true,"cardType":"DC","key":"6225380004804588","messages":[],"stat":"ok"}  
[javascript]  view plain  copy
  1. {"bank":"BJBANK","validated":true,"cardType":"CC","key":"1475288866977-8125-10.208.0.26-684929885","messages":[],"stat":"ok"}  
[javascript]  view plain  copy
  1. {"validated":false,"key":"62129611060012231","stat":"ok","messages":[{"errorCodes":"CARD_BIN_NOT_MATCH","name":"cardNo"}]}  
该接口返回银行Bin号的合法与否(validated),所属银行(bank),银行卡类型(cardType,DC:借记卡,CC:信用卡)。

本来想在前台页面使用,因涉及跨域操作,所以使用jsonp,但是返回的数据浏览器始终报接收数据语法错误,一直找不出具体原因,使用代码如下:

[javascript]  view plain  copy
  1. $.ajax({  
  2.         url: 'https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo='+cardNum+'&cardBinCheck=true',  
  3.         type: "get",  
  4.         dataType: "jsonp",  
  5.         async:false,  
  6.         jsonp:'callback',  
  7.         jsonpCallback:'success_jsonpCallback',  
  8.         success: function(data) {  
  9.             var ob = data;  
  10.         }  
  11.     });  
Firebug始终提示返回数据缺少";",js无法正常执行。这一块也不是很熟悉,以后有机会再研究。

通过后台可以正常调用,通过http Get方法调用,代码如下:

[java]  view plain  copy
  1. public static String HttpGet(String url) {  
  2.     // 关闭HttpClient系统日志;  
  3.     System.setProperty("org.apache.commons.logging.Log","org.apache.commons.logging.impl.SimpleLog");  
  4.     System.setProperty("org.apache.commons.logging.simplelog.showdatetime","true");  
  5.     System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient","stdout");  
  6.   
  7.     HttpClient httpClient = new DefaultHttpClient();  
  8.     HttpGet get = new HttpGet(url);  
  9.     HttpResponse response = null;  
  10.     HttpEntity httpEntity = null;  
  11.     String content = null;  
  12.     try {  
  13.         response = httpClient.execute(get);  
  14.         if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
  15.             //判断gzip,解压缩  
  16.             if(!ObjectUtil.isEmpty(response.getLastHeader("Content-Encoding")) && (response.getLastHeader("Content-Encoding").toString()).indexOf("gzip")>=0){  
  17.                 response.setEntity(new GzipDecompressingEntity(response.getEntity()));  
  18.             }  
  19.             httpEntity = response.getEntity();  
  20.             content = EntityUtils.toString(httpEntity);  
  21.         }  
  22.     } catch (Exception e) {  
  23.         e.printStackTrace();  
  24.     } finally {  
  25.         if (null != httpEntity) {  
  26.             try {  
  27.                 httpEntity.consumeContent();  
  28.             } catch (IOException e) {  
  29.                 e.printStackTrace();  
  30.             }  
  31.         }  
  32.     }  
  33.     return content;  
  34. }  
[java]  view plain  copy
  1. public static void main(String[] args) throws IOException {  
  2.     String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=621226***600******2&cardBinCheck=true";  
  3.     String res = HttpClientUtil.HttpGet(url);  
  4.     System.out.println(res);  
  5.     JSONObject jsonOb = JSON.parseObject(res);  
  6.     String bank = jsonOb.getString("bank");  
  7.     System.out.println(bank);  
  8. }  
打印数据如下:

{"bank":"ICBC","validated":true,"cardType":"DC","key":"6212261106001211212","messages":[],"stat":"ok"}
ICBC


支付宝银行合作伙伴页:https://ab.alipay.com/i/yinhang.htm

支付宝银行简码页:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.M7qlQG&treeId=63&articleId=103763&docType=1

参考文档:https://www.digglife.net/articles/cnbankcard.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值