The Luhn test is used by some credit card companies to distinguish valid credit card numbers from what could be a random selection of digits.
Those companies using credit card numbers that can be validated by the Luhn test have numbers that pass the following test:
- Reverse the order of the digits in the number.
- Take the first, third, … and every other odd digit in the reversed digits and sum them to form the partial sum s1
- Taking the second, fourth … and every other even digit in the reversed digits:
-
- Multiply each digit by two and sum the digits if the answer is greater than nine to form partial sums for the even digits
- Sum the partial sums of the even digits to form s2
- If s1 + s2 ends in zero then the original number is in the form of a valid credit card number as verified by the Luhn test.
For example, if the trial number is 49927398716:
Reverse the digits: 61789372994 Sum the odd digits: 6 + 7 + 9 + 7 + 9 + 4 = 42 = s1 The even digits: 1, 8, 3, 2, 9 Two times each even digit: 2, 16, 6, 4, 18 Sum the digits of each multiplication: 2, 7, 6, 4, 9 Sum the last: 2 + 7 + 6 + 4 + 9 = 28 = s2 s1 + s2 = 70 which ends in zero which means that 49927398716 passes the Luhn test
The task is to write a function/method/procedure/subroutine that will validate a number with the Luhn test, and use it to validate the following numbers:
- 49927398716
- 49927398717
- 1234567812345678
- 1234567812345670
#include <iostream> using namespace std; int toInt(const char c) { return c-'0'; } int confirm( const char *id) { bool is_odd_dgt = true; int s = 0; const char *cp; for(cp=id; *cp; cp++); while(cp > id) { --cp; int k = toInt(*cp); if (is_odd_dgt) { s += k; } else { s += (k!=9)? (2*k)%9 : 9; } is_odd_dgt = !is_odd_dgt; } return 0 == s%10; } int main( ) { const char * t_cases[] = { "49927398716", "49927398717", "1234567812345678", "1234567812345670", NULL, }; for ( const char **cp = t_cases; *cp; cp++) { cout << *cp << ": " << confirm(*cp) << endl; } return 0; }
C++11
#include <iostream> #include <vector> #include <algorithm> using namespace std; bool luhn( const string& id) { static const int m[10] = {0,2,4,6,8,1,3,5,7,9}; // mapping for rule 3 bool is_odd_dgt = false; auto lambda = [&](int a, char c) {return a + ((is_odd_dgt = !is_odd_dgt) ? c-'0' : m[c-'0']);}; int s = std::accumulate(id.rbegin(), id.rend(), 0, lambda); return 0 == s%10; } int main( ) { auto t_cases = {"49927398716", "49927398717", "1234567812345678", "1234567812345670"}; auto print = [](const string & s) {cout << s << ": " << luhn(s) << endl;}; for_each(t_cases.begin(), t_cases.end(), print); return 0; }
Content is available under GNU Free Documentation License 1.2.