2013-12-22 3 views
5

У меня есть вопрос относительно следующего программирования.Подтвердить номер кредитной карты, используя алгоритм luhn

Номера кредитных карт соответствуют определенным шаблонам. Кредитная карта должна иметь от 13 до 16 цифр. Она должна начинаться с:

• 4 для карты Visa

• 5 для мастер-карт

• 37 карт American Express

В 1954 году Ганс Лун из IBM предложил алгоритм для проверки кредита номера карт. Алгоритм полезен для определения правильности ввода номера карты или проверки подлинности кредитной карты сканером. Почти все номера кредитных карт генерируются в соответствии с этой проверкой действительности, обычно известной как проверка Луна или проверка модуля 10, которая может быть описана следующим образом. Для иллюстрации рассмотрим номер карты 4388576018402625.

  1. Двойная каждая вторая цифра справа налево. Если удвоение цифры приводит к двузначному числу, добавьте две цифры, чтобы получить одноразрядное число.

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. Добавить все одиночные цифры номера с шага 4 1 + 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 <= 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

Я дал ответ на ваш второй пост, по-видимому, такой же вопрос сегодня - см. [link] (http://stackoverflow.com/questions/20740444/check-credit-card-validity-using-luhn-algorithm). –

ответ

1

Есть два способа, чтобы разделить ваш int в List<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

это реализация алгоритма Лун, который я использую только для 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 с входной длиной номера.

Он будет работать на Visa, указанных в вопросе. (Я тестировал)

+0

does not work for diners card – jonney

1

Вот моя реализация формулы Лун.

/** 
* 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 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 
} 

Теперь вы можете использовать этот метод для выполнения алгоритма Лун:

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; 
} 
} 
Смежные вопросы