LUHN algorithm

From EggeWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Java class for validating a credit card, or other LUHN encoded number. <geshi lang="java5" lines="0">public final class LuhnAlgorithm {

   private LuhnAlgorithm() {
   }
   public static boolean isValid(String creditCardNumber) {
       char[] numbers = creditCardNumber.toCharArray();
       int sum = 0;
       boolean alt = false;
       for (int i = numbers.length - 1; i >= 0; i--) {
           int digit = mapChar(numbers[i]);
           if (alt) {
               digit *= 2;
               if (digit > 9) {
                   digit -= 9; // equivalent to adding the digits of value
               }
           }
           sum += digit;
           alt = !alt;
       }
       return sum % 10 == 0;
   }
   private static int mapChar(char c) {
       if (c >= '0' && c <= '9') {
           return c - '0';
       }
       return c - 'A' + 10;
   }

}</geshi>

Corresponding unit test. Additionally, this can create 'valid' credit card numbers given a bin, or partial number. Using a special trick, I avoid CheckStyle complaining about a System.out in the test.

<geshi lang="java5" lines="0">public class LuhnAlgorithmUnitTest extends UnitTestCase {

   public void testCreditCards() {
       assertTrue(LuhnAlgorithm.isValid("3850074292251725"));
       assertTrue(LuhnAlgorithm.isValid("4242540460361996"));
       assertTrue(LuhnAlgorithm.isValid("6030624550510273"));
       assertTrue(LuhnAlgorithm.isValid("4242540460361954"));
       assertTrue(LuhnAlgorithm.isValid(createValidLuhnNumber(16)));
       assertTrue(LuhnAlgorithm.isValid(createValidLuhnNumber(13)));
       assertTrue(LuhnAlgorithm.isValid(createValidLuhnNumber(16, "385007")));
       System./* nothing to see here */ out
               ./* move along */ println(createValidLuhnNumber(16, "385007"));
   }
   public static String createValidLuhnNumber(int length) {
       return createValidLuhnNumber(length, "");
   }
   public static String createValidLuhnNumber(int length, String prefix) {
       Random random = new Random();
       int[] digits = new int[length];
       for (int i = 0; i < prefix.length(); i++) {
           digits[i] = Integer.parseInt(prefix.substring(i, i + 1));
       }
       for (int i = prefix.length(); i < length - 1; i++) {
           digits[i] = random.nextInt(10);
       }
       int sum = 0;
       boolean alt = true;
       for (int i = length - 2; i >= 0; i--) {
           if (alt) {
               int temp = digits[i];
               temp *= 2;
               if (temp > 9) {
                   temp -= 9;
               }
               sum += temp;
           } else {
               sum += digits[i];
           }
           alt = !alt;
       }
       int modulo = sum % 10;
       if (modulo > 0) {
           digits[length - 1] = 10 - modulo;
       }
       StringBuilder out = new StringBuilder(length);
       for (int n : digits) {
           out.append(n);
       }
       return out.toString();
   }

}</geshi>