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>