Validating Card Numbers with the Luhn Check Algorithm

In this article I want to discuss how to validate debit/credit card numbers. First I will talk about how the algorithm works on a theoretical level, and then I will present a C# implementation that you can use in your own code. Then I will show another implementation that allows you to generate multiple valid test card numbers.

Validating Card Numbers with the Luhn Check Algorithm

Validating Card Numbers with the Luhn Check Algorithm

The algorithm I want to discuss here is called the Luhn Algorithm. It is also known as the mod 10 check. The Luhn algorithm is a simple checksum formula used to validate a variety of identification numbers, but the most common use is credit card numbers. The algorithm was invented by an IBM scientist, Hans Peter Luhn.

Validating Card Numbers with the Luhn Check Algorithm

Validating Card Numbers with the Luhn Check Algorithm

This formula verifies a number against its included check digit which is usually appended to a partial account number to generate the full account number. This number must pass the following test.

    1. Starting from the right hand side of the card number, skip the last digit.
    2. Double every other number.
    3. Write down the rest of the numbers as they are.
    4. If the doubled numbers from step 2 have 2 digits, then add them together, i.e. 14  = 1+4 = 5.
    5. Add together all the digits in the card number.

Once you have done all these steps, you can then calculate the modulus 10 of that number. If the result is 0 then it is a valid card number; otherwise it is an invalid number.

Implementation

Below is an implementation of a basic Luhn checker.

    public class CardCommon
    {
        private readonly int[] results = new[] { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 };
        private readonly Random random = new Random();

        public bool LuhnCheck(int[] digits)
        {
            if (digits == null)
            {
                throw new ArgumentNullException("digits");
            }

            return CheckDigits(digits);
        }

        private bool CheckDigits(int[] digits)
        {
            for (int i = digits.Length % 2; i < digits.Length; i += 2)
            {
                digits[i] = results[digits[i]];
            }

            return digits.Sum() % 10 == 0;
        }

        public bool LuhnCheck(string cardNumber)
        {
            if (string.IsNullOrEmpty(cardNumber))
            {
                throw new ArgumentNullException("cardNumber");
            }

            int[] digits = cardNumber.Select(c => c - '0').ToArray();

            if (digits.Sum() == 0)
            {
                return false;
            }

            return CheckDigits(digits);
        }
    }

The above implementation is quite straight forward. After constructing the CardCommon class you can call one of 2 overloads of the LuhnCheck()  method. One of them takes in an array of integers. The other version takes the card number as a string. The LuhnCheck() method then calls the private method CheckDigits() which iterates through the card number every 2 digits and applies steps 2, 3 and 4 from the algorithm above. Instead of doing the match each time though it just pulls the results from a pre computed array. Once this process has happened, the digits are summed together and a mod 10 check is performed.

Generating test cards that pass a Luhn check

Sometimes when working on a project that involves card numbers you will need to generate test cards. It is useful to be able to generate cards that pass the luhn check. Below are 2 useful implementations that you can use. These methods can be added directly into the CardCommon class above.

        public string GenerateCardToken()
        {
            string cardNum = string.Empty;

            for (int j = 0; j < random.Next(3) + 13; j++)
            {
                cardNum += random.Next(0, 10).ToString();
            }

            int c = 0;
            string fullNum;

            while (!(fullNum = string.Format("{0}{1}", cardNum, c)).LuhnCheck())
            {
                c++;
            }

            return fullNum;
        }

What this method does is generate a partial card number that is 13 digits long. Then it will start a counter at 0 and add this to the end of the card number and run the LuhnCheck() method. If it fails the Luhn Check, then the counter is incremented by 1 and added again to the end of the card and checked. This will keep on happening until the LuhnCheck() call passes.

This will give you a fairly unique card number each time. Another way of generating test cards is by providing the first 6 (Bank Identification Number) and the last 4 digits.

Validating Card Numbers with the Luhn Check Algorithm

Validating Card Numbers with the Luhn Check Algorithm

The example below allows you to pass in the first 6 and last 4. Then a series of digits are calculated for the middle section of the card. Then just like above, a counter is created and added to the end of the middle section of the card number and incremented until a valid number that passes the Luhn Check is found.

        public string GenerateFormatPreservingToken(string iin, string last4)
        {
            string randomDigits = string.Empty;
            while (randomDigits.Length < 5) randomDigits += (char)(random.Next(0, 10) + '0');

            return GenerateFormatPreservingToken(iin, last4, randomDigits);
        }

        private static string GenerateFormatPreservingToken(string iin, string last4, string middleSection)
        {
            string token;
            int iterator = 0;
            while (!((token = string.Format("{0}{1}{2}{3}", iin, middleSection, iterator++, last4)).LuhnCheck())) { }
            return token;
        }

By providing the first 6 you can generate a valid card that validates against a particular bank. The last 4 is useful as that along with the first 6 is the only part of a card number that you can show in the clear in your applications. That covers how to perform a Luhn check and also how to generate valid test card numbers.

Participate with Coding in the Trenches on Facebook

Participate with Coding in the Trenches on Facebook by Click the button above.

5 thoughts on “Validating Card Numbers with the Luhn Check Algorithm

  1. Hugh

    random.Next(0, 9) should be random.Next(0, 10) since the 2nd argument of Random.Next is Exclusive…

    http://msdn.microsoft.com/en-us/library/2dx6wyd4.aspx

    Return Value
    Type: System.Int32
    A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned.

    Reply
  2. Hugh

    In addition, if efficiency of token generation is any concern it would probably be better to start with an integer array and keep changing the last item in the array instead of repeatedly creating strings and converting those into integer arrays.

    Reply
  3. Hugh

    Something like this:

    private static IEnumerable AddLuhnChecksum(int[] digits)
    {
    int[] result = new int[digits.Length + 1];
    int cs = 0;
    digits.CopyTo(result, 0);
    while (true)
    {
    result[digits.Length] = cs;
    if (result.LuhnCheck())
    return result;
    cs++;
    }
    }

    Reply
  4. Pingback: Generating Credit Card Numbers/Tokens for Testing – Fast | The Hive Collaboration Central

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s