Click here to Skip to main content
13,209,725 members (53,817 online)
Click here to Skip to main content
Add your own
alternative version

Stats

167.2K views
2.5K downloads
31 bookmarked
Posted 30 Dec 2012

Validate credit card number with Mod 10 algorithm

, 15 Jan 2013
Rate this:
Please Sign up or sign in to vote.
Article provides details about Mod 10 algorithm and how to validate a credit card number with mod 10 algorithm using C#.

Introduction

All you know what information contains in your NIC number. But do you know what information contains in the Credit Card Number? Following article provides brief details about what information contain in your credit card and demonstrates to how to validate credit card number using mod 10 (Luhn) algorithms with C#.

Background 

Card Length 

Typically, credit card numbers are all numeric and the length of the credit card number is between 12 digits to 19 digits. 

  • 14, 15, 16 digits – Diners Club
  • 15 digits – American Express
  • 13, 16 digits – Visa
  • 16 digits - MasterCard  

For more information please refer http://en.wikipedia.org/wiki/Bank_card_number.

Hidden information

  1.  Major Industry Identifier (MII) 
  2. The first digit of the credit card number is the Major Industry Identifier (MII). It designates the category of the entry which issued the card.    

    • 1 and 2 – Airlines 
    • 3 – Travel
    • 4 and 5 – Banking and Financial
    • 6 – Merchandising and Banking/Financial
    • 7 – Petroleum
    • 8 – Healthcare, Telecommunications
    • 9 – National Assignment 
  3. Issuer Identification Number 
  4. The first 6 digits are the Issuer Identification Number. It will identify the institution that issued the card. Following are some of the major IINs. 

  5. Amex – 34xxxx, 37xxxx 
  6. Visa – 4xxxxxx 
  7. MasterCard – 51xxxx – 55xxxx 
  8. Discover – 6011xx, 644xxx, 65xxxx 
  9. Account Number 
  10. Taking away the 6 identifier digits and the last digits, remaining digits are the person’s account number (7th and following excluding last digits) 

  11. Check digits   

Last digit is known as check digits or checksum. It is used to validate the credit card number using Luhn algorithm (Mod 10 algorithm). 

For more information refer: http://en.wikipedia.org/wiki/Bank_card_number and http://en.wikipedia.org/wiki/List_of_Issuer_Identification_Numbers.

Luhn algorithm (Mod 10)  

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 US and Canadian Social Insurance Numbers. It was created by IBM scientist Hans Peter Luhn. (http://en.wikipedia.org/wiki/Luhn_algorithm)

When you implementing eCommerce application, It is a best practice validating credit card number before send it to the bank validation.

Here are the Luhn steps which can used to validate the credit card number. 

4 0 1 2 8 8 8 8 8 8 8 8 1 8 8 1  

Step 1 - Starting with the check digit double the value of every other digit (right to left every 2nd digit)  

Step 2 - If doubling of a number results in a two digits number, add up the digits to get a single digit number. This will results in eight single digit numbers.

Step 2 

Step 3 - Now add the un-doubled digits to the odd places

 

Step 4 - Add up all the digits in this number

If the final sum is divisible by 10, then the credit card number is valid. If it is not divisible by 10, the number is invalid. 

Using the code   

Following code sample validates your credit card number against Mod 10. 

public static bool Mod10Check(string creditCardNumber)
{
    //// check whether input string is null or empty
    if (string.IsNullOrEmpty(creditCardNumber))
    {
        return false;
    }

    //// 1.	Starting with the check digit double the value of every other digit 
    //// 2.	If doubling of a number results in a two digits number, add up
    ///   the digits to get a single digit number. This will results in eight single digit numbers                    
    //// 3. Get the sum of the digits
    int sumOfDigits = creditCardNumber.Where((e) => e >= '0' && e <= '9')
                    .Reverse()
                    .Select((e, i) => ((int)e - 48) * (i % 2 == 0 ? 1 : 2))
                    .Sum((e) => e / 10 + e % 10);


    //// If the final sum is divisible by 10, then the credit card number
    //   is valid. If it is not divisible by 10, the number is invalid.            
    return sumOfDigits % 10 == 0;            
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Tharaka MTR
Technical Lead Eyepax IT Consulting (Pvt) Ltd.
Sri Lanka Sri Lanka
Having more than 9 year hands-on industry experience in software development
Responsible for designing, implementing and managing complex software systems with stringent up-time requirement.

Visit my blog

You may also be interested in...

Pro

Comments and Discussions

 
You must Sign In to use this message board.
Spacing  Layout  Per page   
QuestionCredit Card Validation
Member 1325662321-Jun-17 19:28
memberMember 1325662321-Jun-17 19:28 
Hi..

Is this code validates all credit card numbers and show alert for all credit card details..like

your credit card number is valid and Visa card, your credit card number is valid and Master card so on..

is this code shows like that if not can i get a code like that


Thank you
BugSo close, but wrong - you need to use the checksum correctly!
Chaz.NYC28-Oct-16 8:58
memberChaz.NYC28-Oct-16 8:58 
I tried your code and had problems.

I searched and found this: https://en.wikipedia.org/wiki/Luhn_algorithm

You were right, up to the checksum/mod test where YOU claim: "If the final sum is divisible by 10, then the credit card number is valid. If it is not divisible by 10, the number is invalid." This is NOT true. Here's how to do it:

Step 4 - Add up all the digits in this number (except the checksum)
Step 5 - If (sum x 9) MOD 10 = checksum, you have a valid card!

This will work for ALL credit cards.

If you were to do this in QBASIC, it would look like this:

A = 0
FOR X = LEN(CARD$) - 1 TO 1 STEP -2
W = VAL(MID$(CARD$,X,1)) * 2
IF W > 9 THEN W = W - 9
A = A + W
IF X > 1 THEN A = A + VAL(MID$(CARD$, X-1, 1))
NEXT X

IF (A * 9) MOD 10 = VAL(RIGHT$, CARD$, 1) THEN PRINT "GOOD CARD!" ELSE PRINT "BAD CARD!"

Variables
---------
A is the accumulator, adding up the digits on the card, every other one, doubled (doubled -9 if over 9).
CARD$ is the credit card, numeric portion only
W is a working variable (temporary to hold the number before added to the accumulator)
X is the position of the digit being worked upon, starting at the end of the card number (-1) and working backwards.

The ever-so-important difference is that the adjusted card number sum is multiplied by 9 and run through a modula 10 check. The result should be the last digit on the card (if it's a good number!)
- Chaz

GeneralRe: So close, but wrong - you need to use the checksum correctly!
Member 1270317420-Jun-17 2:07
memberMember 1270317420-Jun-17 2:07 
Can you please provide an example value (not a valid card number, obviously) where your code and the article's code disagree?

The reason that I ask is that as far as I can see, the two approaches are equivalent, and the Wikipedia page lists both.

When you calculate (A * 9) MOD 10, this is the same as 10 - (A MOD 10) for positive A.

Some examples,
A = 0  =>  0 MOD 10 = 0
A = 1  =>  9 MOD 10 = 9
A = 2  =>  18 MOD 10 = 8
A = 3  =>  27 MOD 10 = 7
A = 4  =>  36 MOD 10 = 6
A = 5  =>  45 MOD 10 = 5
A = 6  =>  54 MOD 10 = 4
A = 7  =>  63 MOD 10 = 3
A = 8  =>  72 MOD 10 = 2
A = 9  =>  81 MOD 10 = 1
A = 10  =>  90 MOD 10 = 0
A = 11  =>  99 MOD 10 = 9
A = 12  =>  108 MOD 10 = 8
A = 13  =>  117 MOD 10 = 7


Therefore, if the Check Digit is 10 - (A MOD 10), then adding this to A will yeild a multiple of 10, as the article states. The check digit is a single decimal digit, so there will be only one value that can bring A up to a multiple of 10.

If there is a difference between the two approaches, then the Wikipedia page needs updating, as might a lot of credit card code that has made some unfortunate people very grumpy. If you can find and post an example value, that'd be great.
QuestionMy vote of 5
Member 1199207113-Oct-15 10:22
memberMember 1199207113-Oct-15 10:22 
Excellent and concise code. Thank you very much.
AnswerRe: My vote of 5
Tharaka MTR15-Oct-15 7:24
professionalTharaka MTR15-Oct-15 7:24 
Thumbs Up | :thumbsup:

QuestionGood job bro..
HBK_SHAAN19-Aug-15 7:11
memberHBK_SHAAN19-Aug-15 7:11 
very useful ...thnks.
AnswerVB.Net version
kozchris12-Feb-15 6:23
memberkozchris12-Feb-15 6:23 
Not sure if the Floor function is necessary in the C# version it seems to me that it should be. Here is the VB.Net version.

Imports System.Linq
 
Shared Function Mod10Check(ByVal creditCardNumber As String) As Boolean
            ' check whether input string is null or empty
            If (String.IsNullOrEmpty(creditCardNumber)) Then
                Return False
            End If
 
            ' 1.    Starting with the check digit double the value of every other digit
            ' 2.    If doubling of a number results in a two digits number, add up
            '   the digits to get a single digit number. This will results in eight single digit numbers
            ' 3. Get the sum of the digits
            Dim sumOfDigits As Integer = creditCardNumber.Where(Function(e) (e >= "0"c AndAlso e <= "9"c)) _
                .Reverse() _
                .Select(Function(e, i) ((Asc(e) - 48) * (IIf(i Mod 2 = 0, 1, 2)))) _
                .Sum(Function(e) (Math.Floor(e / 10) + e Mod 10))
 
            ' If the final sum is divisible by 10, then the credit card number
            '   is valid. If it is not divisible by 10, the number is invalid.
            Return (sumOfDigits Mod 10) = 0
        End Function

AnswerValidation and the Law
SlaveDrivinBoss12-Dec-14 11:42
memberSlaveDrivinBoss12-Dec-14 11:42 
Many people here fail to recognise that unless they work for a company that provides payment gateways or for a bank, they (you programmers) should not be asking your site visitors / clients for any kind of banking information... PERIOD.

How many people here can say that they can not only safely store and transmit this information as a 3rd party and pay for HTTPS and also the Certificates that will be needed.

Then, consider another problem, security, physical security... If you have had varied jobs, some that have taken me to locations on maps that just are not listed... You get to see a few interesting things on your travels, anyway, my point, security comes in many forms and to provide proper security at a physical level you will need a building that you can bold the server to the floor, the building has bars to all windows and high security locks, you then have a patrol guard with a menacing looking dog that walks the perimeter of the land where this secure data centre is located.

Getting the picture on how seriously banks take your personal data, so why is it that I read about people wanting to validate a credit debit card, no hint of any alarm bells ringing with regard to the client (customers) security, not a single whiff of that aroma called suspicion...
GeneralRe: Validation and the Law
Member 300191019-Dec-14 11:31
memberMember 300191019-Dec-14 11:31 
Is the air clearer up there on that pedestal?
We are talking validating a credit card, plenty of companies validate credit cards, you don't need to store any of the information.

-Edward
GeneralRe: Validation and the Law
Member 1199207113-Oct-15 10:00
memberMember 1199207113-Oct-15 10:00 
If your name didn't say it all that post certainly did. Nothing is worse than working for a slave driver other than working for an ignorant slave driver.

Validating a credit card number BEFORE it gets sent off to the processor is not the same as storing it. A lot of people do it to avoid being charged by the processor for sending an invalid number.

"How many people here can say that they can not only safely store and transmit this information as a 3rd party and pay for HTTPS and also the Certificates that will be needed."

Believe me, anyone who has to deal with storing credit card info knows all about this stuff (it's called PCI compliance, BTW) which is why we don't store them or, if we do, use a third party PCI compliant service to do it for us i.e. authorize.net's CIM.
GeneralRe: Validation and the Law
Member 1270317425-Aug-16 3:04
memberMember 1270317425-Aug-16 3:04 
I have to disagree with some of what you said.

According to the PCI, if you store, process or transmit credit card numbers, then your organisation MUST be PCI compliant and complete the PCI Attestation. The PCI requirements do not just apply to organisations that store credit card numbers.

This means that if any Credit Card numbers touch any of your servers, even if they are encrypted, then you must contact the PCI SSC for advice about completing a PCI compliance. If people are attempting to use an algorithm such as this to validate credit card numbers before sending them off to a processor, they need to be PCI compliant.

The only way you can take credit card payments and not complete the PCI compliance is if you use a payment page system provided by your credit card processor, so that you either redirect your customer to their site, or have an iframe in your page hosting a page from the processor.

tl;dr OP is correct, if credit card data touches your server, you have to know the law.
QuestionWhy do you need to subtract each digit by 48?
Richard Hu12-Aug-14 21:13
memberRichard Hu12-Aug-14 21:13 
When you iterate through each digit, what is this (int) e - 48 for?
If first digit of card number is 5, then it will become -43?
AnswerRe: Why do you need to subtract each digit by 48?
Tharaka MTR13-Aug-14 8:34
professionalTharaka MTR13-Aug-14 8:34 
I think you missed the logic. Here card number processing as individual char. Therefore you got the ASCII value of the char digit.
for ex:
ASCII value of '0' = 48
ASCII value of '5' = 53

so to get the actual value you have to minus that by 48
for ex:
char '5' => 53
so digit 5 => 53-48 =5

Home this make sense.

GeneralRe: Why do you need to subtract each digit by 48?
Richard Hu13-Aug-14 15:00
memberRichard Hu13-Aug-14 15:00 
Thank you, that makes sense. I didn't know (int)e would convert char digit to ASCII value.
I wonder what if we use Convert.ToInt16(e) here instead, will this be more readable or have impact on performance?
GeneralMy vote of 5
Grant Winney23-Jul-14 12:37
memberGrant Winney23-Jul-14 12:37 
Thanks for breaking this down step by step. It was a very interesting read and helped me implement some cc validation for a project I'm in the middle of.
GeneralRe: My vote of 5
Tharaka MTR23-Jul-14 21:52
professionalTharaka MTR23-Jul-14 21:52 
Thank you for 5v Thumbs Up | :thumbsup:

QuestionLamda
majed samyal18-Sep-13 0:46
membermajed samyal18-Sep-13 0:46 
Thanks! Can you please explain the Lambda Query Logic?
AnswerRe: Lamda
Tharaka MTR18-Sep-13 23:50
professionalTharaka MTR18-Sep-13 23:50 
Well, tell me what you can understand by looking at the expression and what you can't. That way I can give you better explanation.

QuestionDistinction Between Frequent Flyer and Credit Cards
Predrag Kos5-Jun-13 2:45
memberPredrag Kos5-Jun-13 2:45 
Tharaka,

THank you for this. Can you please tell me how can you be sure when scanning magnetic stripe whether you have scanned frequent flyer card or credit card? first digit does not apply. British airways frequent flyer number starts with 6, Lufthansa starts with 9, Delta starts with 2 (so far the only one according to your description.)

With kind regards,

Pedja
QuestionMy vote 5
Yaseer Arafat1-Jun-13 11:46
memberYaseer Arafat1-Jun-13 11:46 
Thanks
Yaseer Arafat
Senior Software Engineer
Wooskie Inc
email:mike@wooskie.com
Web:www.wooskie.com

AnswerRe: My vote 5
Tharaka MTR2-Jun-13 2:15
professionalTharaka MTR2-Jun-13 2:15 
Thanks for v5 Thumbs Up | :thumbsup:

GeneralMy vote of 5
Rohan Leuva18-Apr-13 1:45
memberRohan Leuva18-Apr-13 1:45 
Very good explanation Even for beginners.
GeneralRe: My vote of 5
Tharaka MTR18-Apr-13 1:50
memberTharaka MTR18-Apr-13 1:50 
Thanks for the v5.

Generalthanks you very much
benjamin9x15-Apr-13 15:34
memberbenjamin9x15-Apr-13 15:34 
thanks you very much

GeneralRe: thanks you very much
Tharaka MTR5-Jun-13 19:33
professionalTharaka MTR5-Jun-13 19:33 
Great Thumbs Up | :thumbsup:

QuestionAlternative method.
George Swan17-Jan-13 7:55
memberGeorge Swan17-Jan-13 7:55 

Thanks for posting. There is a method that's twice as fast using a foreach loop. It avoids using the modulus operator within the main loop. But it's not as neat as your solution.



   public static bool Mod10Check(string creditCardNumber)
        {
            //// check whether input string is null or empty or spaces
 
            if (string.IsNullOrWhiteSpace(creditCardNumber))
            {
                return false;
            }
 
            int sumOfDigits = 0;
            int index = 0;
            foreach (int digit in creditCardNumber.Where(e => e >= '0' && e <= '9').Reverse())
            {
                int temp = (index % 2 == 0) ? digit - 48 : (digit - 48) * 2;
                sumOfDigits += temp < 10 ? temp : temp - 9;
                index++;
            }
            return sumOfDigits % 10 == 0;
        }
 

 

Regards


AnswerRe: Alternative method.
Tharaka MTR17-Jan-13 8:56
memberTharaka MTR17-Jan-13 8:56 
Hi George,
Thank you for sharing your comments.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171020.1 | Last Updated 16 Jan 2013
Article Copyright 2012 by Tharaka MTR
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid