银行卡号合法性验证小结
关于银行卡号合法性的验证,网上主流的验证算法是luhn算法,代码如下:
/** * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位 * @author mengrang * @since 2016/09/18 */ public static char getBankCardCheckCode(String nonCheckCodeCardId){ if(nonCheckCodeCardId == null || nonCheckCodeCardId.trim().length() == 0 || !nonCheckCodeCardId.matches("\\d+")||nonCheckCodeCardId.trim().length()<15 ||nonCheckCodeCardId.trim().length()>18) { //如果传的数据不合法返回N return 'N'; } char[] chs = nonCheckCodeCardId.trim().toCharArray(); int luhmSum = 0; // 执行luh算法 for(int i = chs.length - 1, j = 0; i >= 0; i--, j++) { int k = chs[i] - '0'; if(j % 2 == 0) { //偶数位处理 k *= 2; k = k / 10 + k % 10; } luhmSum += k; } return (luhmSum % 10 == 0) ? '0' : (char)((10 - luhmSum % 10) + '0'); }银行卡号最后一位是校验位。
但是对于一些地方性的商业银行,该算法并不适用,实际应用中发现平安银行(原深圳发展银行16位借记卡)老卡没办法通过luhn算法。
无奈只能验证下银行卡Bin号的合法性,实际卡号的合法性移交给金融支付接口来判断,这一块没有算法支持。。。
网上最多验证Bin号的合法性最多的就是查表发,代码着实麻烦,所以网上各种查,最终发现了个良心接口,阿里提供的验证Bin号的免费接口:
https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=待验证银行卡号&cardBinCheck=true
返回json数据如下:
{"bank":"SPABANK","validated":true,"cardType":"DC","key":"6225380004804588","messages":[],"stat":"ok"}
{"bank":"BJBANK","validated":true,"cardType":"CC","key":"1475288866977-8125-10.208.0.26-684929885","messages":[],"stat":"ok"}
{"validated":false,"key":"62129611060012231","stat":"ok","messages":[{"errorCodes":"CARD_BIN_NOT_MATCH","name":"cardNo"}]}该接口返回银行Bin号的合法与否(validated),所属银行(bank),银行卡类型(cardType,DC:借记卡,CC:信用卡)。
本来想在前台页面使用,因涉及跨域操作,所以使用jsonp,但是返回的数据浏览器始终报接收数据语法错误,一直找不出具体原因,使用代码如下:
$.ajax({ url: 'https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo='+cardNum+'&cardBinCheck=true', type: "get", dataType: "jsonp", async:false, jsonp:'callback', jsonpCallback:'success_jsonpCallback', success: function(data) { var ob = data; } });Firebug始终提示返回数据缺少";",js无法正常执行。这一块也不是很熟悉,以后有机会再研究。
通过后台可以正常调用,通过http Get方法调用,代码如下:
public static String HttpGet(String url) { // 关闭HttpClient系统日志; System.setProperty("org.apache.commons.logging.Log","org.apache.commons.logging.impl.SimpleLog"); System.setProperty("org.apache.commons.logging.simplelog.showdatetime","true"); System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient","stdout"); HttpClient httpClient = new DefaultHttpClient(); HttpGet get = new HttpGet(url); HttpResponse response = null; HttpEntity httpEntity = null; String content = null; try { response = httpClient.execute(get); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { //判断gzip,解压缩 if(!ObjectUtil.isEmpty(response.getLastHeader("Content-Encoding")) && (response.getLastHeader("Content-Encoding").toString()).indexOf("gzip")>=0){ response.setEntity(new GzipDecompressingEntity(response.getEntity())); } httpEntity = response.getEntity(); content = EntityUtils.toString(httpEntity); } } catch (Exception e) { e.printStackTrace(); } finally { if (null != httpEntity) { try { httpEntity.consumeContent(); } catch (IOException e) { e.printStackTrace(); } } } return content; }
public static void main(String[] args) throws IOException { String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=621226***600******2&cardBinCheck=true"; String res = HttpClientUtil.HttpGet(url); System.out.println(res); JSONObject jsonOb = JSON.parseObject(res); String bank = jsonOb.getString("bank"); System.out.println(bank); }打印数据如下:
{"bank":"ICBC","validated":true,"cardType":"DC","key":"6212261106001211212","messages":[],"stat":"ok"}
ICBC
支付宝银行合作伙伴页:https://ab.alipay.com/i/yinhang.htm