|
Using the Luhn Algorithm...
Validate credit card numbers, Canadian Social Insurance Numbers, and other unique numbers using the Luhn algorithm.
By: John Kilgo
Date: November 16, 2003
Download the code.
Printer Friendly Version
br>
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.
|