How do I implement the Luhn algorithm?

后端 未结 8 1601
被撕碎了的回忆
被撕碎了的回忆 2020-12-21 09:50

I am trying to create a program to validate 10 to 12 digit long number sequences based on the luhn algorithm, but my program keeps on telling me that every number is invalid

相关标签:
8条回答
  • 2020-12-21 10:11

    I use this function in an app for checking card number validity :

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

    Hope it helps,

    0 讨论(0)
  • 2020-12-21 10:12

    You should be subtracting '0' from tmp, not 0. Subtracting 0 returns the ASCII value, which you don't want.

    0 讨论(0)
  • 2020-12-21 10:14

    If you use Java 10 or higher, you can use the following code:

    public static boolean luhn(String s) {
        IntUnaryOperator sumDigits = n -> n / 10 + n % 10;
        var digits = s.chars()
                      .map(Character::getNumericValue)
                      .toArray();
        return IntStream.rangeClosed(1, digits.length)
                        .map(i -> digits.length - i)
                        .map(i -> i % 2 == 0 ? digits[i] : sumDigits.applyAsInt(digits[i] * 2))
                        .sum() % 10 == 0;
    }
    

    It's the functional approach to this algorithm.

    0 讨论(0)
  • 2020-12-21 10:20

    Newcomers to this post/question can check appropriate Wikipedia page for solution. Below is the Java code copy-pasted from there.

    public class Luhn
    {
            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);
            }
    }
    
    0 讨论(0)
  • 2020-12-21 10:21

    use org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit.LUHN_CHECK_DIGIT.isValid(number)

    Maven Dependency:

    <dependency>
        <groupId>commons-validator</groupId>
        <artifactId>commons-validator</artifactId>
        <version>1.5.1</version>
    </dependency>
    
    0 讨论(0)
  • 2020-12-21 10:22

    Here's some functions I wrote to both calculate the check digit for a given number and to verify a given number sequence and extract the number from it.

    To calculate the check digit for a given number:

    /**
     * Generates the check digit for a number using Luhn's algorithm described in detail at the following link:
     * https://en.wikipedia.org/wiki/Luhn_algorithm
     *
     * In short the digit is calculated like so:
     * 1. From the rightmost digit moving left, double the value of every second digit. If that value is greater than 9,
     *    subtract 9 from it.
     * 2. Sum all of the digits together
     * 3. Multiply the sum by 9 and the check digit will be that value modulo 10.
     *
     * @param number the number to get the Luhn's check digit for
     * @return the check digit for the given number
     */
    public static int calculateLuhnsCheckDigit(final long number) {
        int     sum       = 0;
        boolean alternate = false;
        String  digits    = Long.toString(number);
    
        for (int i = digits.length() - 1; i >= 0; --i) {
            int digit = Character.getNumericValue(digits.charAt(i)); // get the digit at the given index
            digit = (alternate = !alternate) ? (digit * 2) : digit;  // double every other digit
            digit = (digit > 9)              ? (digit - 9) : digit;  // subtract 9 if the value is greater than 9
            sum += digit;                                            // add the digit to the sum
        }
    
        return (sum * 9) % 10;
    }
    

    To verify a sequence of digits using Luhn's algorithm and extract the number:

    /**
     * Verifies that a given number string is valid according to Luhn's algorithm, which is described in detail here:
     * https://en.wikipedia.org/wiki/Luhn_algorithm
     *
     * In short, validity of the number is determined like so:
     * 1. From the rightmost digit (the check digit) moving left, double the value of every second digit. The check
     *    digit is not doubled; the first digit doubled is the one immediately to the left of the check digit. If that
     *    value is greater than 9, subtract 9 from it.
     * 2. Sum all of the digits together
     * 3. If the sum modulo 10 is equal to 0, then the number is valid according to Luhn's algorithm
     *
     * @param luhnsNumber the number string to verify and extract the number from
     * @return an empty Optional if the given string was not valid according to Luhn's algorithm
     *         an Optional containing the number verified by Luhn's algorithm if the given string passed the check
     */
    public static Optional<Long> extractLuhnsNumber(final String luhnsNumber) {
        int     sum       = 0;
        boolean alternate = true;
        Long    number    = Long.parseLong(luhnsNumber.substring(0, luhnsNumber.length() - 1));
    
        for (int i = luhnsNumber.length() - 1; i >= 0; --i) {
            int digit = Character.getNumericValue(luhnsNumber.charAt(i)); // get the digit at the given index
            digit = (alternate = !alternate) ? (digit * 2) : digit;       // double every other digit
            digit = (digit > 9)              ? (digit - 9) : digit;       // subtract 9 if the value is greater than 9
            sum += digit;                                                 // add the digit to the sum
        }
    
        return (sum % 10 == 0) ? Optional.of(number) : Optional.empty();
    }
    
    0 讨论(0)
提交回复
热议问题