财务软件中经常会判断一张银行卡是否是信用卡,这是一个比较普遍的需求。
算法来源:Java实现信用卡校验_南 墙-CSDN博客
当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过 Luhn 算法来验证通过。
该校验的过程:
1 从卡号最后一位数字开始,逆向将奇数位(1、3、5等等)相加。
2 从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,则将其减去9),再求和。
3 将奇数位总和加上偶数位总和,结果应该可以被10整除。
示例
卡号是:5432123456788881
逆向奇数位为 4 2 2 4 6 8 8 1 和 = 35
逆向偶数位乘以2(有些要减去9)的结果:1 6 2 6 1 5 7 7,求和 = 35。
最后 35 + 35 = 70 可以被10整除,认定校验通过。
算法来源:第六章第三十一题(金融应用:信用卡号的合法性验证)(Financial: credit card number validation) - 编程练习题答案_putongdeyang-CSDN博客
package CreditCard;
import java.util.ArrayList;
import java.util.List;
/**
* @className: CreditCard
* @description: 信用卡博客参考
* https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardBinCheck=true&cardNo=6259553770002775
* https://www.cnblogs.com/ygw1010/p/9448374.html
* https://blog.csdn.net/putongdeyang/article/details/106242021
* @date: 2021/10/30
* @author: cakin
*/
public class CreditCard {
public static void main(String[] args) {
List<String> list = new ArrayList();
list.add("356XXXXX2780");
list.add("6228XXX5012");
list.add("62170XXXX999690147");
list.add("62XXXXXXXXX651");
list.add("6XXXXX002775");
// 该算法不对
System.out.println("-----------------------算法1------------------------");
checkCreditCardWrong(list);
// https://blog.csdn.net/putongdeyang/article/details/106242021
List<Long> list1 = new ArrayList();
System.out.println("-----------------------算法2------------------------");
list1.add(35682XX27232780L);
list1.add(6228XX0210783865012L);
list1.add(621XX4229999690147L);
list1.add(621XX63800289732L);
list1.add(6226XX011176880L);
list1.add(6217XX100020631719L);
list1.add(622XX3878253741579L);
list1.add(62XX67000008674794L);
list1.add(6XX4850290872651L);
list1.add(6259XX3770002775L);
checkCreditCardRight(list1);
}
private static void checkCreditCardRight(List<Long> list) {
list.stream().forEach(number ->{
if (isVa1id(number) && divide(number))
System.out.println(number + "是信用卡");
else
System.out.println(number + "不是信用卡");
});
}
// Step 0
public static boolean isVa1id(long number) {
if (prefixMatched(number,4) || prefixMatched(number,5) ||
prefixMatched(number,37) || prefixMatched(number,6)) {
return (number + "").length() >= 13 && (number + "").length() <= 16;
}
else
return false;
}
// Get the result from Step 2
public static int getEven(long number) {
int getEven = 0;
for (int i = 0; i < (number+"").length(); i+=2) {
char n = (number + "").charAt(i);
int num = Integer.parseInt(Character.toString(n));
if (num * 2 > 9)
num = (num * 2 / 10) + (num * 2 % 10);
else if (num * 2 < 10)
num = num * 2;
getEven += num;
}
return getEven;
}
// Get the result from Step 3
public static int getOdd(long number) {
int getOdd = 0;
for (int i = 1; i < (number+"").length(); i+=2) {
char n = (number + "").charAt(i);
int num = Integer.parseInt(Character.toString(n));
getOdd += num;
}
return getOdd;
}
// Return sum
public static int sumOfOddAndEven(long number) {
return getEven(number) + getOdd(number);
}
// Return true if the digit d is a prefix for number
public static boolean prefixMatched(long number, int d) {
String strNumber = number + "";
int charNumber0 = Integer.parseInt(strNumber.substring(0,(d+"").length()));
return charNumber0 == d;
}
public static boolean divide(long d) {
return sumOfOddAndEven(d) % 10 == 0;
}
private static void checkCreditCardWrong(List<String> list) {
list.stream().forEach(item -> {
int sum1 = 0, sum2 = 0;
for (int i = item.length() - 1, j = 1; i >= 0; i--, j++) {
if (j % 2 == 1)
sum1 = sum1 + (item.charAt(i) - '0');
else {
int temp = (item.charAt(i) - '0') * 2;
if (temp >= 10)
temp = temp - 9;
sum2 = sum2 + temp;
}
}
if ((sum1 + sum2) % 10 == 0)
System.out.println(item + "是信用卡");
else
System.out.println(item + "不是信用卡");
});
}
}
注:银行卡属于敏感信息,进行了简单脱敏处理。
-----------------------算法1------------------------
XXXXXXXXXXXX是信用卡
XXXXXXXXXXXX5012是信用卡
XXXXXXXXXXXX0147是信用卡
XXXXXXXXXXXX2651是信用卡
XXXXXXXXXXXX2775是信用卡
-----------------------算法2------------------------
XXXXXXXXXXXX780不是信用卡
XXXXXXXXXXXX3865012不是信用卡
XXXXXXXXXXXX90147不是信用卡
XXXXXXXXXXXX9732是信用卡
XXXXXXXXXXXX6880是信用卡
XXXXXXXXXXXX631719不是信用卡
XXXXXXXXXXXX41579不是信用卡
XXXXXXXXXXXX8674794不是信用卡
XXXXXXXXXXXX72651是信用卡
XXXXXXXXXXXX02775是信用卡
注:银行卡属于敏感信息,进行了简单脱敏处理。
这两个算法得出的结论不一致,不能判断一张银行卡是否是信用卡,实际卡的类型也和上面两种算法得出的结论不一致。
如果真的想判断一张卡的类型是否是信用卡,想通过在网上搜索一个比较好的算法,似乎不太靠谱,因为中国有中国的算法,国外有国外的算法。各银行有各银行的算法,不是一个简单的算法就能兼容所有场景。
比较靠谱的有两种方案:
1 对接中国银联,它的兼容性应该是最强的,也是万能的。
2 对接上游API支付接口,看上游API支付接口是否提供了查询银行卡类型的API,如果有就万幸了,如果没有,看对接方能否提供,如果不能提供,就只有采用方案1了。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/121046549
内容来源于网络,如有侵权,请联系作者删除!