This isn't beautiful, but it's better than string splitting implementations. Feel free to take it and make of it what you will.
Code:
/**
* Verify Luhn Algorithm check digits
*
* @author Craig Ringer <
[email protected]>
*/
public class LuhnAlgorithm {
/**
* Given the input `l' which has a Luhn check digit,
* return true if the Luhn checksum test passes or false
* otherwise.
*
* See http://en.wikipedia.org/wiki/Luhn_algorithm
*
* @param l Input with check digit
* @return true if check digit correct for input
*/
public static boolean verify(long n) {
if (n < 10)
return false;
long s = 0;
for (long i = 0L; i < Math.ceil(Math.log10(n)); i++) {
// Extract a digit and double it
final long doubled = ((n / (long)Math.pow(10L,i)) % 10L) * (i % 2L + 1L);
// Add the value of each digit of the result to the running
// total. If the result is, eg `12', we'd add 3 : 1+2=3.
s += doubled % 10L + doubled / 10L;
}
return s % 10 == 0;
}
/**
* Strip the Luhn check digit from a number. Of course, this is just a
* division by 10... but this way you can see why.
* @param n Luhn-check-digit-containing value
* @return Value without check digit
*/
public static long stripCheckDigit(long n) {
return n / 10;
}
}
Code:
/**
* JUnit tests for LuhnAlgorithm.java
*/
public class LuhnAlgorithmTest {
private static final long[] okLuhns = {
10L,
378282246310005L,
371449635398431L,
378734493671000L,
5610591081018250L,
30569309025904L,
38520000023237L,
6011111111111117L,
6011000990139424L,
3530111333300000L,
3530111333300000L,
3566002020360505L,
5555555555554444L,
5105105105105100L,
3530111333300000L,
4111111111111111L,
3530111333300000L,
4012888888881881L,
4222222222222L,
2323200577663554L,
1234567812345670L
};
private static final long[] badLuhns = {
-1L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L
};
public LuhnAlgorithmTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
/**
* Test of verify method, of class LuhnAlgorithm.
*/
@Test
public void testVerify() {
System.out.println("verify");
for (long l : okLuhns) {
assertTrue( LuhnAlgorithm.verify(l));
}
for (long l : badLuhns) {
assertFalse( LuhnAlgorithm.verify(l) );
}
}
}