在 Java 中编写 Luhn 算法

Programming a Luhn Algorithm in Java

我正在尝试在 Java 内编写 Luhn 算法。

我当前的代码是:

import java.util.Scanner;

public class luhnAlgorithm {

public static void main(String[] args) {
    System.out.println("main() : Entry Point");

    Scanner input = new Scanner(System.in);

    long num;
    int digit;
    int sum = 0;
    System.out.println("Enter the digits of a credit card number : ");
    num = input.nextLong();


    while (num > 0) {
        digit = (int) num % 10;
        num = num / 10;

        if (num % 2 != 0 ) {
            digit *= 2;
        }

        if (digit > 9) {
            digit -= 9;
        }

        sum += digit;
    }

    if(sum % 10 == 0) {
        System.out.println("Credit card number is valid.");
    }
    else 
        System.out.println("Credit card number is invalid. Please try again.");


    System.out.println("main() : Exit Point");


    }

}

我遇到的问题是,当我输入有效的信用卡号码时,例如:4012888888881881(通过 PayPal Test Credit Card Accounts),它说它无效。但是当我输入我自己的借记卡号码时,它说它是有效的。

我知道这里有些代码乱七八糟,我就是想不通是什么。

如有任何帮助,我们将不胜感激,并在此先致谢!

我想我知道问题出在哪里了。你用错误的方式做乘法:

    if (num % 2 != 0 ) {
        digit *= 2;
    }

当 num 为奇数时你乘以数字,在 Luhn 的算法中当这个数字在数字中从右向左移动的偶数位置时你应该乘以数字。尝试考虑添加一些索引,这将帮助您了解数字是否在偶数位置。

您可以考虑将整数拆分为数组,然后检查数组的索引是否为偶数,或者在 while 循环中添加一些索引。

仔细研究这个https://en.wikipedia.org/wiki/Luhn_algorithm

例如,如果你有 68 那么你有:第一次迭代:digit = 8,num = 6 和 sum =8 第二次迭代:digit = 6,num = 0 这里你应该将你的数字乘以 2,因为它在数字上是偶数,但你不这样做并且 sum = 14 而不是 20

好吧,我真的想通了:)。

import java.util.Scanner;

/*
* Author : Jonathan Patterson
* Date : 10/28/15
* Program : Luhn Algorithm; validates credit card numbers
*/

public class luhnAlgorithm {

public static void main(String[] args) {
    System.out.println("main() : Entry Point");

    Scanner input = new Scanner(System.in);

    long num;
    double digit = 0;
    int sum = 0;
    int n = 1;
    int i = 0;
    System.out.println("Enter the digits of a credit card number : ");
    num = input.nextLong();

    while (num > 0) {
        digit = num % 10;
        num = num / 10;

        System.out.println(n + " digit is : " + digit);

        if (i % 2 != 0 ) {
            digit *= 2;
        }

        System.out.println(n + " digit is : " + digit);

        if (digit > 9) {
            digit = (digit % 10) + 1;
        }
        else 
            digit *= 1;

        System.out.println(n + " digit is : " + digit);

        sum += digit;
        n++;
        i++;
    }

    System.out.println("Sum of the digits is : " +sum);

    if(sum % 10 == 0) {
        System.out.println("Credit card number is valid.");
    }
    else 
        System.out.println("Credit card number is invalid. Please try again.");


    System.out.println("main() : Exit Point");


   }

}

添加一个额外的答案以防其他人找到这个post。

有一个有效实现的 bitbucket 项目: https://bitbucket.org/javapda/npi-validator/src/master/

这 if 用于验证 NPI 提供者编号,这是 Luhn 算法的实现。

package org.bitbucket.javapda.npi;

import java.util.ArrayList;
import java.util.List;

public class NpiValidator {

    private String npi;

    public NpiValidator(String npi) {
        this.npi = npi.trim();
    }

    public boolean isValid() {
        return npi.length() == 10 && complies();
    }

    private boolean complies() {
        if (!npi.matches("[0-9]{10}")) {
            return false;
        }
        Character lastDigit = npi.charAt(9);
        List<Integer> everyOther = listWithEveryOtherDoubled(npi.substring(0, 9));
        int sum = 0;
        for (Integer num : everyOther) {
            sum += sumOfDigits(num);
        }
        int total = sum + 24; // 24 to account for 80840
        int units = total % 10;
        int checkDigit = (units != 0) ? (10 - units) : units;
        return (Character.getNumericValue(lastDigit) == checkDigit);

    }

    private List<Integer> listWithEveryOtherDoubled(String str) {
        List<Integer> nums = new ArrayList<Integer>();
        for (int i = 0; i < str.length(); i++) {
            if (i % 2 == 0) {
                nums.add(2 * Character.getNumericValue(str.charAt(i)));
            } else {
                nums.add(Character.getNumericValue(str.charAt(i)));
            }
        }
        return nums;
    }

    private static int sumOfDigits(int number) {
        int num = number;
        int sum = 0;
        while (num > 0) {
            sum += (num % 10);
            num = num / 10;
        }
        return sum;
    }

    public static void main(String[] args) {
        System.out.println("Hello, World!");
        // System.out.println(sumOfDigits(16));
        System.out.println("1234567890".matches("[0-9]{10}"));
        System.out.println("123456789".matches("[0-9]{10}"));
    }

}