Using the Luhn Algorithm...
Validate credit card numbers, Canadian Social Insurance Numbers, and other unique numbers using the Luhn algorithm.
The Luhn algorithm was developed in the 1960's as a way to validate unique numbers such as credit card number, social insurance numbers, insurance numbers and other number forms. The algorithm is in the public domain and is in wide use today. The example program presented in this article will use the algorithm to validate credit card numbers, but, as stated above, you may find other uses for it. The logic presented in the example program will work for any type of number to be validated.
The algorithm works by suming some form of the digits of the number working from right to left. The resulting total must be evenly divisible by 10 for the number to be valid. Starting with the next to last digit (and working left) every other digit is doubled. However, if the doubled digit is greater than or equal to 10, rather than using the doubled value, you use the sum of the two digits. For example, if you double 7 we will add 5 (1+4) to the total rather than 14. In actual practice we will keep two running subtotals. One will be the sum of the odd numbered positions (starting with the right-most digit). The other will be the sum of the "doubled" digits of the even numbered positions (starting with the second right-most digit). A short example may help. Let's say our number is "8 4 6 6". Working from right to left the odd numbered positions (6 and 4) are simply summed (10). The even numbered positions (6 and 8) are "doubled". 6 doubled is 12 so we instead use 3 (1+2). 8 doubled is 16 so we instead use 7 (1+6). The sum for our even numbered positions is 10 (3+7). Our total sum for both even and odd numbered positions is 20. Since 20 is evenly divisible by 10, the number 8466 is a valid number.
The above logic is essentially the way our example program will work. It took me a minute or two to get my brain around it but once you understand the concept of the algorithm, it is really quite simple. Let's get to the code. First the .aspx page which simply contains a textbox to input a credit card number, a submit button and a couple of label controls.
|
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="ValidateCreditCard.aspx.vb" Inherits="DotNetJohn.ValidateCreditCard"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>ValidateCreditCard</title> <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1"> <meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1"> <meta name=vs_defaultClientScript content="JavaScript"> <meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5"> </head> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:textbox id="txtCardNum" Runat="server" /> <asp:button id="btnSubmit" onclick="ValidateCard" Runat="server" Text="Validate" /> <p> <asp:label id="lblValid" Runat="server" /> </p> <p> <asp:label id="lblCardType" Runat="server" /> </P> </form> </body> </html> |
The code behind page is presented below. It is essentially doing what we did in the little example above. Two subtotals are beining maintained. One is for the odd numbered positions (working from right to left) which are simply summed. The other is for the even numbered positions where the digit is doubled if the result is less than 10, or has the two digits added together if the result is 10 or greater. At the end of the subroutine the two subtotals are added together and compared to Mod 10 to see if the card number is valid or not. The variable intOddNumber is continually set to true or false so that, with each new digit, the program knows which subtotal the digit belongs to and whether to double it or not.
|
Public Class ValidateCreditCard Inherits System.Web.UI.Page ' Web Form Designer Generated Code Omitted Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load lblValid.Text = "" lblCardType.Text = "" End Sub 'Page_Load Sub ValidateCard(Sender As Object, E As EventArgs) Dim strCardNum As String = txtCardNum.Text Dim intOddNumber As Boolean = True 'Odd or even numbered digits within the card number beginning from the right Dim intSubTotalOdd As Integer = 0 'sum of odd (undoubled) set of numbers Dim intSubTotalEven As Integer = 0 'sum of even (doubled) set of numbers Dim strLeftDigit As String 'if number to be added is greater than 10, store the left-most integer Dim strRightDigit As String 'if number to be added is greater than 10, store the right-most integer Dim arrCardNum As Char() = strCardNum.ToCharArray() 'array of individual card numbers Dim intDoubled As Integer 'an even numbered card number, doubled Dim intDigit As Integer 'an individual card number For i As Integer = arrCardNum.Length - 1 To 0 Step -1 intDigit = Int32.Parse(arrCardNum(i).ToString()) If intOddNumber Then 'add the digit to the odd-numbered digits sub-total intSubTotalOdd += intDigit intOddNumber = False Else 'add the doubled digit to the even-numbered digits sub-total intDoubled = intDigit * 2 If intDoubled >= 10 Then 'split the digits and add them together strLeftDigit = intDoubled.ToString().Substring(0, 1) strRightDigit = intDoubled.ToString().Substring(1, 1) intSubTotalEven += Convert.ToInt32(strLeftDigit) + Convert.ToInt32(strRightDigit) Else 'add the doubled number intSubTotalEven += intDoubled End If intOddNumber = True End If Next i 'If the sum is divisible by 10, then the card is valid If(intSubTotalOdd + intSubTotalEven) Mod 10 = 0 Then lblValid.Text = "This Card Is Valid" lblCardType.Text = ShowTypeOfCard(strCardNum) Else lblValid.Text = "This Card Is Invalid" End If End Sub Function ShowTypeOfCard(strCardNum As String) As String If Convert.ToString(strCardNum.Substring(0, 2)) = "34" Or Convert.ToString(strCardNum.Substring(0, 2)) = "37" Then Return "American Express Card." End If If Convert.ToString(strCardNum.Substring(0, 4)) = "6011" Then Return "Discover Card." End If If Convert.ToInt32(strCardNum.Substring(0, 2)) >= 51 And Convert.ToInt32(strCardNum.Substring(0, 2)) <= 55 Then Return "Master Card." End If If Convert.ToString(strCardNum.Substring(0, 1)) = "4" Then Return "Visa Card." End If Return "Unknown credit card" End Function End Class |
You may download the code here.