2013-12-22 57 views
5

我對以下編程任務有疑問。使用luhn算法驗證信用卡號碼

信用卡號碼符合特定模式。信用卡必須有13到16位數字。它必須先從:

•4 Visa卡

•5主卡

•37美國運通卡

在1954年,IBM的漢斯·盧恩提出的算法驗證信用卡號。該算法對於確定卡號是否正確輸入或掃描儀是否正確掃描信用卡很有用。幾乎所有的信用卡號碼都是在此有效性檢查後生成的,通常稱爲Luhn支票或Modulus 10支票,可以描述如下。爲了說明,請考慮卡號4388576018402625.

  1. 從右到左每隔兩位數字雙擊一次。如果一個數字加倍會得到一個2位數的數字,請將這兩個數字相加得到一位數字。

2×2 = 4

2×2 = 4

4×2 = 8

1×2 = 2

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

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

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

4×2 = 8

  1. 從步驟1 4 + 4 8 + 2 3 + 1 + 7 + 8 = 37

  2. 添加所有的個位數
  3. 在奇數地方添加所有數字從右卡號到左

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

  1. 薩姆從步驟2和步驟3的結果 37 + 37 = 74

  2. 如果來自步驟的結果是被10整除,卡號碼是有效的;否則,它是無效的。例如,號碼4388576018402625無效,但號碼4388576018410707是有效的Visa卡;號碼6011000593748745無效,但號碼6011000593748746是有效的發現卡。

我試圖解決它,如下面的代碼:

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 <= 9) { 
      return number; 
     } else { 
      int firstDigit = number % 10; 
      int secondDigit = (int) (number/10); 

      return firstDigit + secondDigit; 
     } 
    } 
    public static int sumOfOddPlace(long number) { 
     int result = 0; 

     while (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. "); 
     } 

    } 
} 

我的問題是如何使用數組來存儲,而不是使用長數的信用卡號碼。

+2

你可以使用'String' ... –

+0

我已經給了一個答案到今天看起來相同問題的第二篇文章 - 請參閱[鏈接](http://stackoverflow.com/questions/20740444/check-credit-card-validity-using-luhn-algorithm)。 –

回答

1

有兩種方法來分割你的intList<Integer>

  1. 使用%10與您使用並存儲到一個List
  2. 轉換爲String,然後採取數值

這裏有幾個快速示例

public static void main(String[] args) throws Exception { 
    final int num = 12345; 
    final List<Integer> nums1 = splitInt(num); 
    final List<Integer> nums2 = splitString(num); 
    System.out.println(nums1); 
    System.out.println(nums2); 
} 

private static List<Integer> splitInt(int num) { 
    final List<Integer> ints = new ArrayList<>(); 
    while (num > 0) { 
     ints.add(0, num % 10); 
     num /= 10; 
    } 
    return ints; 
} 

private static List<Integer> splitString(int num) { 
    final List<Integer> ints = new ArrayList<>(); 
    for (final char c : Integer.toString(num).toCharArray()) { 
     ints.add(Character.getNumericValue(c)); 
    } 
    return ints; 
} 
1

這是LUHN算法的實現。如果你想使用它的任何號碼與您輸入的號碼長度更換所有16,我用了只有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"); 

它將在題所給簽證號碼工作。(我測試)

+0

不適用於用餐卡 – jonney

1

這裏是我的實現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; 
    } 
} 

我通過在卡c我從card掃描儀和店購買,並cn我通過在checkNumber = card.charAt((card.length() - 1));

1

好的,這可以通過類型轉換爲字符串和一些Java東西來解決。不要忘記數字和代表數字的字符不一樣。 ! '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<cardNumbers.length; i++) { 
        if (i % 2 == 0) 
         nxtDigit = (nxtDigit > 4) ? (nxtDigit * 2 - 10) + 1 : nxtDigit * 2; 
        sum += nxtDigit; 
       } 
       return (sum % 10); 
      } 
0
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;i<d;i++) 
    { 
     if(i%2!=0) 
     { 
      card[i]=card[i]*2; 
      if(card[i]>9) 
       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; 
} 
}