无法弄清楚Luhn检查的错误

时间:2015-10-20 14:08:07

标签: java eclipse luhn

它使用luhn检查告诉我卡是有效还是无效 4388576018402626无效 4388576018410707有效 但它一直告诉我一切都是无效的:/ 关于做什么或在哪里看的任何提示都会很棒。我被困了几个小时。 如果人们告诉我有关如何找到代码未按预期工作的原因的任何提示,也会有所帮助。 即时通讯使用eclipse和java

public class Task11 {

   public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        System.out.print("Enter a credit card number as a long integer: ");
        long number = input.nextLong();


        if (isValid(number)) {
            System.out.println(number + " is valid");
        } else {
            System.out.println(number + " is invalid");
        }


    }

    public static boolean isValid(long number) {

        return (getSize(number) >= 13) && (getSize(number) <= 16)
                && (prefixMatched(number, 4) || prefixMatched(number, 5) || prefixMatched(number, 6) || prefixMatched(number, 37))
                && (sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 == 0;
    }

    public static int sumOfDoubleEvenPlace(long number) {

        int result = 0;

        long start = 0;

        String digits = Long.toString(number);

        if ((digits.length() % 2) == 0) {
            start = digits.length() - 1;
        } else {
            start = digits.length() - 2;
        }


        while (start != 0) {


            result += (int) ((((start % 10) * 2) % 10) + (((start % 10) * 2) / 2));

            start = start / 100;

        }

        return result;
    }


    public static int getDigit(int number) {

        return number % 10 + (number / 10);

    }

    public static int sumOfOddPlace(long number) {

        int result = 0;

        while (number != 0) {

            result += (int) (number % 10);

            number = number / 100;

        }

        return result;

    }

    public static boolean prefixMatched(long number, int d) {

        return getPrefix(number, getSize(d)) == d;

    }

    public static int getSize(long d) {

        int numberOfDigits = 0;

        String sizeString = Long.toString(d);
        numberOfDigits = sizeString.length();

        return numberOfDigits;

    }


    public static long getPrefix(long number, int k) {

        String size = Long.toString(number);

        if (size.length() <= k) {
            return number;
        } else {
            return Long.parseLong(size.substring(0, k));
        }
    }
}

2 个答案:

答案 0 :(得分:1)

你应该修改你的isValid()方法,以便在它不起作用时写下来,如下所示:

 public static boolean isValid(long number) {
        System.err.println();
        if(getSize(number) < 13){
            System.out.println("Err: Number "+number+" is too short");
            return false;
        } else if (getSize(number) > 16){
  public static boolean isValid(long number) {
        System.err.println();
        if(getSize(number) < 13){
            System.out.println("Err: Number "+number+" is too short");
            return false;
        } else if (getSize(number) > 16){
            System.out.println("Err: Number "+number+" is too long");
            return false;
        } else if (! (prefixMatched(number, 4) || prefixMatched(number, 5) || prefixMatched(number, 6) || prefixMatched(number, 37)) ){
            System.out.println("Err: Number "+number+" prefix doesn't match");
            return false;
        } else if( (sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 != 0){
            System.out.println("Err: Number "+number+" doesn't have sum of odd and evens % 10. ");
            return false;
        }  
        return true;
    }

我对你的问题的猜测是getPrefix()方法,你也应该在这里添加一些日志。

编辑:所以,有更多的时间来帮助你(不知道它是否仍然是必要的,但无论如何)。另外,我更正了我写的方法,有一些错误(比如,getSize(number) >= 13的反面是getSize(number) < 13)... 首先,使用一组数据进行测试会更快,而不是每次都输入值(添加要检查的值):

public static void main(String[] args) {
           long[] luhnCheckSet = {
                   0, // too short
                   1111111111111111111L, // too long (19)
                   222222222222222l // prefix doesn't match
                   4388576018402626l, // should work ?
                   };

        //System.out.print("Enter a credit card number as a long integer: ");
        //long number = input.nextLong();

        for(long number : luhnCheckSet){
            System.out.println("Checking number: "+number);
            if (isValid(number)) {
                System.out.println(number + " is valid");
            } else {
                System.out.println(number + " is invalid");
            }
            System.out.println("-");
        }
    }

我不知道这个细节,但我认为你应该一直使用String,并且只在需要时解析为long(如果数字超过19个字符,则可能无法解析)它long)。 不过,还有多头。

我详细记录了您的getPrefix()日志并将d放入参数中(这是一个很好的习惯,要小心您比较的原始类型):

public static boolean prefixMatched(long number, long d) {
            int prefixSize = getSize(d);
            long numberPrefix = getPrefix(number, prefixSize);
            System.out.println("Testing prefix of size "+prefixSize+" from number: "+number+". Prefix is: "+numberPrefix+", should be:"+d+", are they equals ? "+(numberPrefix == d));
            return numberPrefix == d;
        }

还不知道这段代码有什么问题,但看起来它来自上一次测试: 我没有这样做但是你应该从sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10创建一个方法并记录数字和总和(就像我在prefixMatched()中所做的那样)。在两种方法中添加日志以确保它获得您想要的结果/应该如此工作。 你用过调试器吗?如果可以的话,它可以比添加大量日志更快!

祝你好运

答案 1 :(得分:0)

编辑:

以下是工作功能,下面我提供了一个更短,更有效的解决方案:

public class CreditCardValidation {

  public static void main(String[] args) {
 Scanner in = new Scanner(System.in);
    int count = 0;
    long array[] = new long [16];
   do
   {
    count = 0;
    array = new long [16];
    System.out.print("Enter your Credit Card Number : ");
    long number = in.nextLong();
    for (int i = 0; number != 0; i++) {
    array[i] = number % 10;
    number = number / 10;
    count++;
    }
   }
    while(count < 13); 
    if ((array[count - 1] == 4) || (array[count - 1] == 5) ||     (array[count-  1] == 3 && array[count - 2] == 7)){
        if (isValid(array) == true) {
        System.out.println("\n The Credit Card Number is Valid. ");
    } else {
        System.out.println("\n The Credit Card Number is Invalid. ");
    }
    } else{
      System.out.println("\n The Credit Card Number is Invalid. ");
    }
    in.close();
}

public static boolean isValid(long[] array) {
    int total = sumOfDoubleEvenPlace(array) + sumOfOddPlace(array);        
    if ((total % 10 == 0)) {
      for (int i=0; i< array.length; i++){
        System.out.println(array[i]);}
        return true;
    } else {
      for (int i=0; i< array.length; i++){
        System.out.println(array[i]);}
        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[] array) {
    int result = 0;
    for (int i=0; i< array.length; i++)
    {
    while (array[i] > 0) {
        result += (int) (array[i] % 10);
        array[i] = array[i] / 100;
    }

 }
    System.out.println("\n The sum of odd place is " + result);
    return result;
}

public static int sumOfDoubleEvenPlace(long[] array) {
    int result = 0;
    long temp = 0;
    for (int i=0; i< array.length; i++){
    while (array[i] > 0) {
        temp = array[i] % 100;
        result += getDigit((int) (temp / 10) * 2);
        array[i] = array[i] / 100;
       }
      }


     System.out.println("\n The sum of double even place is " + result);
    return result;
       }
     }

我还找到了一个逻辑线较少的解决方案。我知道您可能正在寻找具有功能的OO方法,从中构建可能会有所帮助。

关于Luhn算法逻辑中的错误的类似问题:

Check Credit Card Validity using Luhn Algorithm

链接到更短的解决方案:

https://code.google.com/p/gnuc-credit-card-checker/source/browse/trunk/CCCheckerPro/src/com/gnuc/java/ccc/Luhn.java

在这里,我用真实的CC编号测试了解决方案:

 public class CreditCardValidation{

    public static boolean Check(String ccNumber)

    {

            int sum = 0;
            boolean alternate = false;
            for (int i = ccNumber.length() - 1; i >= 0; i--)
            {
                    int n = Integer.parseInt(ccNumber.substring(i, i + 1));
                    if (alternate)
                    {
                            n *= 2;
                            if (n > 9)
                            {
                                    n = (n % 10) + 1;
                            }
                    }
                    sum += n;
                    alternate = !alternate;
            }
            return (sum % 10 == 0);
    }

    public static void main(String[] args){
        //String num = "REPLACE WITH VALID NUMBER"; //Valid
        String num = REPLACE WITH INVALID NUMBER; //Invalid
               num = num.trim();
        if(Check(num)){
            System.out.println("Valid");
        }
        else
            System.out.println("Invalid");
        //Check();
    }

}