The Luhn algorithm or Luhn formula, also known as the "modulus 10" or "mod 10" algorithm, is a simple checksum formula used to validate a variety of identification numbers, such as credit card numbers, IMEI numbers, National Provider Identifier numbers in the United States, Canadian Social Insurance Numbers, Israel ID Numbers and Greek Social Security Numbers (ΑΜΚΑ). It was created by IBM scientist Hans Peter Luhn and described in U.S. Patent No. 2,950,048, filed on January 6, 1954, and granted on August 23, 1960.
The algorithm is in the public ___domain and is in wide use today. It is specified in ISO/IEC 7812-1.Cite error: A <ref>
tag is missing the closing </ref>
(see the help page). for a hand-held, mechanical device for computing the checksum. It was therefore required to be rather simple. The device took the mod 10 sum by mechanical means. The substitution digits, that is, the results of the double and reduce procedure, were not produced mechanically. Rather, the digits were marked in their permuted order on the body of the machine.
Implementation examples
Pseudo-Code
function checkLuhn(string purportedCC) { int sum := integer(purportedCC[length(purportedCC)-1]) int nDigits := length(purportedCC) int parity := nDigits modulus 2 for i from 0 to nDigits - 2 { int digit := integer(purportedCC[i]) if i modulus 2 = parity digit := digit × 2 if digit > 9 digit := digit - 9 sum := sum + digit } return (sum modulus 10) = 0 }
C
#include <stdlib.h> // atoi
#include <string.h> // strlen
#include <stdbool.h> // bool
bool checkLuhn(const char *pPurported)
{
int nSum = 0;
int nDigits = strlen(pPurported);
int nParity = (nDigits-1) % 2;
char cDigit[2] = "\0";
for (int i = nDigits; i > 0 ; i--)
{
cDigit[0] = pPurported[i-1];
int nDigit = atoi(cDigit);
if (nParity == i % 2)
nDigit = nDigit * 2;
nSum += nDigit/10;
nSum += nDigit%10;
}
return 0 == nSum % 10;
}
Python
def luhn(purported):
LUHN_ODD_LOOKUP = (0, 2, 4, 6, 8, 1, 3, 5, 7, 9) # sum_of_digits (index * 2)
if not isinstance(purported, str):
purported = str(purported)
try:
evens = sum(int(p) for p in purported[-1::-2])
odds = sum(LUHN_ODD_LOOKUP[int(p)] for p in purported[-2::-2])
return ((evens + odds) % 10 == 0)
except ValueError: # Raised if an int conversion fails
return False
See also
References