使用luhn算法validation信用卡号

我对以下编程任务有疑问。

信用卡号码遵循某些模式。 信用卡的长度必须介于13到16位之间。 它必须从:

•4张Visa卡

•5张万事达卡

•美国运通卡37张

1954年,IBM的Hans Luhn提出了一种validation信用卡号的算法。 该算法可用于确定是否正确输入了卡号或扫描仪是否正确扫描了信用卡。 几乎所有信用卡号都是在此有效性检查后生成的,通常称为Luhn检查或模数10检查,可以描述如下。 例如,请考虑卡号4388576018402625。

  1. 从右到左加倍每秒。 如果数字加倍会产生2位数字,请将两位数相加以得到一位数字。

2 x 2 = 4

2 x 2 = 4

4 x 2 = 8

1 x 2 = 2

6 x 2 = 12(1 + 2 = 3)

5 x 2 = 10(1 + 0 = 1)

8 x 2 = 16(1 + 6 = 7)

4 x 2 = 8

  1. 添加步骤1 4 + 4 + 8 + 2 +3 + 1 + 7 + 8 = 37中的所有单个数字

  2. 在卡号中从右到左添加奇数位置中的所有数字

5 + 6 + 0 + 8 + 0 + 7 + 8 + 3 = 37

  1. 对步骤2和步骤3 37 + 37 = 74的结果求和

  2. 如果步骤的结果可被10整除,则卡号有效; 否则,它无效。 例如,号码4388576018402625无效,但号码4388576018410707是有效的Visa卡; 号码6011000593748745无效,但号码6011000593748746是有效的Discover卡。

我尝试解决它,如下面的代码所示:

import java.util.Scanner; public class CreditCardValidation { public static boolean isValid(long number) { int total = sumOfDoubleEvenPlace(number) + sumOfOddPlace(number); if ((total % 10 == 0) && (prefixMatched(number, 1) == true) && (getSize(number)>=13 ) && (getSize(number)<=16 )) { return true; } else { return false; } } public static int getDigit(int number) { if (number  0) { result += (int) (number % 10); number = number / 100; } return result; } public static int sumOfDoubleEvenPlace(long number) { int result = 0; long temp = 0; while (number > 0) { temp = number % 100; result += getDigit((int) (temp / 10) * 2); number = number / 100; } return result; } public static boolean prefixMatched(long number, int d) { if ((getPrefix(number, d) == 4) || (getPrefix(number, d) == 5) || (getPrefix(number, d) == 3)) { if (getPrefix(number, d) == 3) { System.out.println("\nVisa Card "); } else if (getPrefix(number, d) == 5) { System.out.println("\nMaster Card "); } else if (getPrefix(number, d) == 3) { System.out.println("\nAmerican Express Card "); } return true; } else { return false; } } public static int getSize(long d) { int count = 0; while (d > 0) { d = d / 10; count++; } return count; } public static long getPrefix(long number, int k) { if (getSize(number) < k) { return number; } else { int size = (int) getSize(number); for (int i = 0; i < (size - k); i++) { number = number / 10; } return number; } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Enter a credit card number as a long integer: "); long input = sc.nextLong(); if (isValid(input) == true) { System.out.println("\n" + input + " is Valid. "); } else { System.out.println("\n" + input + " is Invalid. "); } } } 

我的问题是如何使用数组来存储信用卡号而不是使用长号码。

有两种方法可以将int拆分为List

  1. 在使用时使用%10并将其存储到List
  2. 转换为String然后获取数值

这里有几个简单的例子

 public static void main(String[] args) throws Exception { final int num = 12345; final List nums1 = splitInt(num); final List nums2 = splitString(num); System.out.println(nums1); System.out.println(nums2); } private static List splitInt(int num) { final List ints = new ArrayList<>(); while (num > 0) { ints.add(0, num % 10); num /= 10; } return ints; } private static List splitString(int num) { final List ints = new ArrayList<>(); for (final char c : Integer.toString(num).toCharArray()) { ints.add(Character.getNumericValue(c)); } return ints; } 

这是luhn算法实现,我只使用16位数的信用卡号码

 if(ccnum.length()==16){ char[] c = ccnum.toCharArray(); int[] cint = new int[16]; for(int i=0;i<16;i++){ if(i%2==1){ cint[i] = Integer.parseInt(String.valueOf(c[i]))*2; if(cint[i] >9) cint[i]=1+cint[i]%10; } else cint[i] = Integer.parseInt(String.valueOf(c[i])); } int sum=0; for(int i=0;i<16;i++){ sum+=cint[i]; } if(sum%10==0) result.setText("Card is Valid"); else result.setText("Card is Invalid"); }else result.setText("Card is Invalid"); 

如果你想在任何数字上使用它,请用你的输入数字长度替换所有16。

它适用于问题中给出的签证号码。(我测试过)

这是我对Luhn公式的实现。

 /** * Runs the Luhn Equation on a user inputed CCN, which in turn * determines if it is a valid card number. * @param c A user inputed CCN. * @param cn The check number for the card. * @return If the card is valid based on the Luhn Equation. */ public boolean luhn (String c, char cn) { String card = c; String checkString = "" + cn; int check = Integer.valueOf(checkString); //Drop the last digit. card = card.substring(0, ( card.length() - 1 ) ); //Reverse the digits. String cardrev = new StringBuilder(card).reverse().toString(); //Store it in an int array. char[] cardArray = cardrev.toCharArray(); int[] cardWorking = new int[cardArray.length]; int addedNumbers = 0; for (int i = 0; i < cardArray.length; i++) { cardWorking[i] = Character.getNumericValue( cardArray[i] ); } //Double odd positioned digits (which are really even in our case, since index starts at 0). for (int j = 0; j < cardWorking.length; j++) { if ( (j % 2) == 0) { cardWorking[j] = cardWorking[j] * 2; } } //Subtract 9 from digits larger than 9. for (int k = 0; k < cardWorking.length; k++) { if (cardWorking[k] > 9) { cardWorking[k] = cardWorking[k] - 9; } } //Add all the numbers together. for (int l = 0; l < cardWorking.length; l++) { addedNumbers += cardWorking[l]; } //Finally, check if the number we got from adding all the other numbers //when divided by ten has a remainder equal to the check number. if (addedNumbers % 10 == check) { return true; } else { return false; } } 

我将卡片作为ccheckNumber = card.charAt( (card.length() - 1) );传入并存入card ,而对于cn我传入checkNumber = card.charAt( (card.length() - 1) );

好的,这可以通过字符串转换和一些Java 8的东西来解决。 不要忘记数字,代表数字的字符也不一样。 ‘1’!= 1

 public static int[] longToIntArray(long cardNumber){ return Long.toString(cardNumber).chars() .map(x -> x - '0') //converts char to int .toArray(); //converts to int array } 

您现在可以使用此方法执行luhn算法:

  public static int luhnCardValidator(int cardNumbers[]) { int sum = 0, nxtDigit; for (int i = 0; i 4) ? (nxtDigit * 2 - 10) + 1 : nxtDigit * 2; sum += nxtDigit; } return (sum % 10); } 
 public class Creditcard { public static void main(String args[]){ Scanner sc=new Scanner(System.in); String cardno = sc.nextLine(); if(checkType(cardno).equals("U")) //checking for unknown type System.out.println("UNKNOWN"); else checkValid(cardno); //validation } private static String checkType(String S) { int AM=Integer.parseInt(S.substring(0,2)); int D=Integer.parseInt(S.substring(0,4)),d=0; for(int i=S.length()-1;i>=0;i--) { if(S.charAt(i)==' ') continue; else d++; } if((AM==34 || AM==37) && d==15) System.out.println("AMEX"); else if(D==6011 && d==16) System.out.println("Discover"); else if(AM>=51 && AM<=55 && d==16) System.out.println("MasterCard"); else if(((S.charAt(0)-'0')==4)&&(d==13 || d==16)) System.out.println("Visa"); else return "U"; return ""; } private static void checkValid(String S) // S--> cardno { int i,d=0,sum=0,card[]=new int[S.length()]; for(i=S.length()-1;i>=0;i--) { if(S.charAt(i)==' ') continue; else card[d++]=S.charAt(i)-'0'; } for(i=0;i9) sum+=digSum(card[i]); else sum+=card[i]; } else sum+=card[i]; } if(sum%10==0) System.out.println("Valid"); else System.out.println("Invalid"); } public static int digSum(int n) { int sum=0; while(n>0) { sum+=n%10; n/=10; } return sum; } }