LUHN algorithm: Difference between revisions
mNo edit summary |
mNo edit summary |
||
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
Java class for validating a credit card, or other LUHN encoded number. | Java class for validating a credit card, or other LUHN encoded number. | ||
<geshi lang="java5" lines="0"> | <geshi lang="java5" lines="0">public final class LuhnAlgorithm { | ||
public final class LuhnAlgorithm { | |||
private LuhnAlgorithm() { | private LuhnAlgorithm() { | ||
Line 30: | Line 29: | ||
return c - 'A' + 10; | return c - 'A' + 10; | ||
} | } | ||
} | }</geshi> | ||
</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. | 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"> | <geshi lang="java5" lines="0">public class LuhnAlgorithmUnitTest extends UnitTestCase { | ||
public class LuhnAlgorithmUnitTest extends UnitTestCase { | |||
public void testCreditCards() { | public void testCreditCards() { | ||
Line 89: | Line 86: | ||
return out.toString(); | return out.toString(); | ||
} | } | ||
} | }</geshi> | ||
</geshi> | |||
[[Category:Java]] |
Latest revision as of 02:36, 1 October 2007
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>