CREDIT
CARD SECURITY
This excellent tutorial is the work of NTSA, who has very kindly
consented to the TAZ hosting it.
You can find the original post here:
http://www.antionline.com/showthread.php?s=&threadid=230916
Enjoy!
Outline
In this tutorial I am going to cover two types of credit card
validation. The first type of validation is a LUHN check. The second
validation method that I cover examines the use of a cards.ini text
file for credit card type validation.
LUHN checking
Most credit card numbers (including Visa and Mastercard) conform to the
LUHN checksum algorithm. You can calculate the last digit of a card
number, by examining all the preceeding digits. You cannot tell from
this if the card is stolen, but it can be used to check if the user has
made a mistake when entering a card number.
In this article I am publishing both my ASP and PHP LUHN checking
functions.
Card Type validation
The second type of validation is checking that the selected card type
is correct. Each card type - Visa, mastercard etc - has a given length
and prefix. For exampe Visa cards have a prefix of 4 and a length of
either 13 or 16 characters. Because of this you can validate that the
card type that has been selected by the user is accurate.
This part of the code is only provided in ASP - Sorry
A explaination of the LUHN algorithm
Quote:
The following steps are involved in this calculation:
Step 1: Double the value of alternate digits beginning with the first
right-hand digit (low order).
Step 2: Add the individual digits comprising the products obtained in
step 1 to each of the unaffected digits in the original number.
Step 3: Subtract the total obtained in step 2 from the next higher
number ending in 0 [this in the equivalent of calculating the
"tens complement" of the low order digit (unit digit) of the total].
If the total obtained in step 2 is a number ending in zero
(30, 40 etc.), the check digit is 0.
Example:
Account number without check digit: 4992 73 9871
4 9 9 2 7 3 9 8 7 1
x2 x2 x2 x2 x2
----------------------------
18 4 6 16 2
4 + 1 + 8 + 9 + 4 + 7 + 6 + 9 + 1 + 6 + 7 + 2 = 64
70 - 64 = 6
Account number with check digit 4992 73 9871 6
From: http://staff.semel.fi/~kribe/document/luhn.htm
LUHN Check - ASP version
Example Usage
Quote:
CardIsValid = true
if card.luhncheck(p_CardNo) = true then
debug "luhn ok"
else
debug "luhn failed"
CardIsValid = false
end if
The ASP Code!
Code:
'ASP ISO 7812:1987(E) LUHN Checker
'This function was written by Simon Barnett.
(si@ntsa.org.uk)
'Use and distribution of this software is covered
'by open source licence
(http://www.opensource.org/osd.html).
'Please include these comments in any distribution.
Function LuhnCheck(p_cardno)
session("debug") = "false"
if isnumber(p_cardno) = false then
luhncheck = false
else
if len(p_cardno) = 0 then
luhncheck = false
else
tot = 0
chk = right(p_cardno,1)
p_cardno =
left(p_cardno,len(p_cardno)-1)
for n = len(p_cardno)
to 1 step - 2
x =
cint(mid(p_cardno,n,1)) * 2
if
len(x) > 1 then
tot = tot + cint(mid(x,1,1))
'debug mid(x,1,1)
tot = tot + cint(mid(x,2,1))
'debug mid(x,2,1)
else
tot = tot + cint(mid(x,1,1))
'debug mid(x,1,1)
end
if
next
for n =
len(p_cardno)-1 to 1 step - 2
tot
= tot + cint(mid(p_cardno,n,1))
'debug mid(p_cardno,n,1)
next
'debug tot
checkdigit =
cint(cstr(cint(left(cstr(tot),1))+1) & "0") - tot
debug "Checkdigit
should be "&checkdigit
debug "Actual Check
Digit "&chk
if int(chk) =
int(checkdigit) then
luhncheck = true
else
luhncheck = false
end if
end if
end if
End Function
LUHN Check - PHP version
Example Usage
Quote:
// <EXAMPLE USAGE>
if(ValidCard($credit_card)) // Pass credit card details without spaces.
{
echo "Valid Card";
}
else
{
echo "Invalid Card";
}
The PHP Code!
Code:
<?php
function ValidCard($credit_card)
/* PHP ISO 7812:1987(E) LUHN Checker
This function was written by Simon Barnett.
(si@ntsa.org.uk)
Use and distribution of this software is covered
by open source licence
(http://www.opensource.org/osd.html).
Please include these comments in any distribution.
*/
{
$checksum = substr ($credit_card, -1);
// returns checksum
$restnum = substr($credit_card, 0, strlen($credit_card)-1);
// returns rest of credit card number
$calcvals = "";
for ($i = strlen($restnum)+1; $i >= 0; $i=$i-2)
{
$calcvals = $calcvals .
strval(intval(substr($restnum,$i,1))*2);
}
for ($i = strlen($restnum) -2; $i >= 0; $i=$i-2)
{
$calcvals = $calcvals .
strval(intval(substr($restnum,$i,1))*1);
}
$calcvals = substr($calcvals,1);
$count = 0;
for ($i = 0; $i <= strlen($calcvals); $i++) {
$count = $count +
intval(substr($calcvals,$i,1));
}
if(intval(substr(strval((10*(intval(substr(strval
($count),0,1))+1)-$count)),-1))==$checksum)
{
return true;
}
else
{
return false;
}
}
?>
Checking the type of card (ASP)
I didn't want to hard code the card type information for obvious
reasons, not least amongst which is the fact that I'm using code
similar to this over a large number of sites, each with their own list
of accepted cards. So I stored all the information about the fornat of
each of the different credit card companies in an ini file. This ini
file is shown below.
The cards.ini file
Quote:
[Visa]
prefix=4
length=13,16
[Mastercard]
prefix=51,52,53,54,55
length=16
[American Express]
prefix=34,37
length=15
[Dinners Club]
prefix=300,301,302,303,304,305,36,38
length=14
[JCB]
prefix=3
length=16
[Discover]
prefix=6011
length=16
Displaying the list of accepted cards
The CardList routine below reads the cards.ini file given above and
displays each of the credit card types in a drop down combo box. The
returned 'CardType' variable is used validating the card type in the
FormatCheck Function.
Code:
Sub CardList()
cards = split(getcards(),",")
response.write " <select name='CardType' size='1'>"
response.write " <option
selected value=''><-Please Select-></option>"
n = 0
on error resume next
while err.number = 0
response.write "
<option value='"& cards (n) &"'>"& cards (n)
&"</option>"
n = n + 1
wend
response.write " </select>"
End Sub
Function GetCards()
Dim fso, MyFile
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile =
fso.OpenTextFile(replace(request("inipath"),"*","\"), ForReading)
getcards = ""
while not myfile.atendofstream
l = MyFile.ReadLine
if left(l,1) = "[" then
if getcards = "" then
getcards = mid(l,2,len(l)-2)
else
getcards = getcards & "," & mid(l,2,len(l)-2)
end if
end if
wend
End Function
Validating the selected card type
Example Usage
Quote:
CardIsValid = true
if card.formatcheck(p_CardNo,p_CardType) = true then
debug "Format ok"
else
debug "Format failed"
CardIsValid = false
end if
The Code!
Code:
Function FormatCheck(p_CardNo, p_CardType)
Dim fso, MyFile
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile =
fso.OpenTextFile(replace(request("inipath"),"*","\"), ForReading)
f=0
debug "Opening Cards.ini file..."
while not myfile.atendofstream
l = MyFile.ReadLine
if left(l,1) = "[" then
if mid(l,2,len(l)-2) =
p_cardtype then
f = 1
debug "found " & mid(l,2,len(l)-2)
prefix = split(trim(replace(MyFile.ReadLine,"prefix=","")),",")
length = split(trim(replace(MyFile.ReadLine,"length=","")),",")
end if
end if
wend
myfile.close
if f = 0 then
formatcheck = false
else
prefixok = false
n = 0
on error resume next
while err.number = 0
debug "Check Prefix:"
& prefix(n)
if
left(p_cardno,len(prefix(n))) = prefix(n) then
debug left(p_cardno,len(prefix(n))) &"="& prefix(n)
if
err.number = 0 then
prefixok = true
end
if
end if
n = n +1
wend
lengthok = false
n = 0
on error resume next
while err.number = 0
debug "check len: "
& int(length(n))-1
if len(p_cardno) =
int(length(n))-1 then
if
err.number = 0 then
debug len(p_cardno) &"="& int(length(n))-1
lengthok = true
end
if
end if
n = n +1
wend
if lengthok = true and prefixok = true
then
formatcheck = true
else
formatcheck = false
end if
end if
End Function
Original Tutorial
Submitted by nokia for TheTAZZone-TAZForum
Originally posted on March 7th, 2006 here
Do not use, republish, in whole or in part, without the consent of
the Author. TheTAZZone policy is that Authors retain the rights to the
work they submit and/or post...we do not sell, publish, transmit, or
have the right to give permission for such...TheTAZZone merely retains
the right to use, retain, and publish submitted work within it's
Network.

