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.

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.

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.

- Starting from the right hand side of the card number, skip the last digit.
- Double every other number.
- Write down the rest of the numbers as they are.
- If the doubled numbers from step 2 have 2 digits, then add them together, i.e. 14 = 1+4 = 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

**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**

*LuhnCheck()***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.**

*CheckDigits()***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.

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.

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.

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.

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++;

}

}

An ex-colleague of mine has written a more optimized version of the GenerateCardToken method. You can read it here :

http://goadingtheitgeek.blogspot.co.uk/2013/06/generating-credit-card-numberstokens.html