【问题标题】:Can't figure out the error Luhn check无法找出错误 Luhn check
【发布时间】:2016-01-19 05:58:39
【问题描述】:

它应该使用 luhn check 告诉我卡是有效还是无效 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));
        }
    }
}

【问题讨论】:

    标签: java eclipse luhn


    【解决方案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) &gt;= 13 的反面是getSize(number) &lt; 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() 中所做的那样)。在这两种方法中添加日志,以确保它得到你想要的结果/像它应该的那样工作。 你用过调试器吗?可以的话就做吧,比加很多日志还快!

    祝你好运

    【讨论】:

      【解决方案2】:

      编辑:

      这里是工作函数,下面我也提供了一个更短、更有效的解决方案:

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

      【讨论】:

      • 感谢您的所有时间和工作,问题是我必须使用这些方法:/ 因为我们正在学习使用方法。我应该在我的帖子中提到这一点。对不起。顺便说一句,你在我的代码中看到任何错误的东西吗?我一直在寻找,还没有发现问题:/
      • 我刚刚编辑了响应并添加了工作功能。祝你好运。
      猜你喜欢
      • 1970-01-01
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      相关资源
      最近更新 更多