-1

I'm trying to program the Luhn Algorithm within Java.

My current code is :

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


    }

}

The problem I'm having is that when I enter in a valid credit card number, for example : 4012888888881881 (via PayPal Test Credit Card Accounts), it says it's invalid. But when I put in my own debit card number it says it's valid.

I know there's some code messed up in here, I just can't figure out what.

Any help would be appreciated and thanks in advance!

Adam Buchanan Smith
  • 9,422
  • 5
  • 19
  • 39
jon
  • 29
  • 1
  • 3

3 Answers3

4

I think that I know where the problem is. You do the multiplication in a wrong way:

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

You multiply digit when num is odd and in Luhn's algorithm you should multiply digit when this digit is on the even place in number moving from right to the left. Try to think about adding some index which will help you to know if a digit is on even place or not.

You can think about splitting your integer to array and then check if index of array is even or add to your while loop some index.

Carefully study this https://en.wikipedia.org/wiki/Luhn_algorithm

for example if you have 68 then you have: first iteration: digit = 8, num = 6 and sum =8 second iteration: digit = 6, num = 0 here you should multiply your digit by 2, because it is on the even place in number, but you don't do that and sum = 14 instead of 20

Piotrowy
  • 605
  • 8
  • 20
0

Okay I actually figured it out :).

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


   }

}
jon
  • 29
  • 1
  • 3
0

Adding an additional answer to this in case anyone else finds this post.

There is a bitbucket project with a valid implementation: https://bitbucket.org/javapda/npi-validator/src/master/

This if for verifying NPI provider numbers which is an implementation of the Luhn algorithm.

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

}
Nicholas DiPiazza
  • 10,029
  • 11
  • 83
  • 152