It's standard practise for on line bookings these days to take credit or debit card details as a booking security, and we're no exception at
Well House Manor - our hotel for business visitors to Melksham, Wiltshire. There are very many security issues involved, and I am
not going to describe what we can and must do behind the scenes ourselves - rather, I'm going to show you the algorithm that checks that a card number's of the correct format in PHP.
Credit card numbers are typically 16 digits long, although some such as AmEx are a little shorter. The initial digit(s) tell you what type of card you're dealing with - the code below has the current set to the best of my knowledge, but you should check - and then all the digits are taken individually and combined into what is in effect a checksum value. If the checksum comes out as an exact multiple of 10, the number is potentially valid. If the checksum does not come out as a multiple of 10, then you can be sure the number is wrong.
The algorithm used is a clever one that's designed to make it very unlikely that a simple error in giving a credit card number (such as leaving a digit out, getting a digit wrong, or transposing two digits) is very unlikely indeed to lead you to a different valid number. Only in the case of two errors of these types does the probability of an error resulting in a valid code start approaching the 1 in 10 you might expect from a random error.
<?php
/* Some test code!
$ccwrong = array("4xxx xxxx xxxx 1123","4xxx xxxx xxxx 1716");
$ccright = array("4xxx xxxx xxxx 1715","4xxx xxxx xxxx 1111");
foreach (array_merge($ccwrong,$ccright) as $cc) {
list ($type,$valid,$cz) = ccvalidate($cc);
print ("Card $cc is $type and ".($valid?"OK":"Duff")."\n");
}
*/
# Function to take in a credit card number and identify type
# also check the check digits
function ccvalidate($ccno) {
# 1. Is is the right no. of digits (allowing commonly places spaces and dashes)
$card = "";
if (preg_match('/^\s*4\d{3}[-\s]*\d{4}[-\s]*\d{4}[-\s]*\d{4}\s*$/',$ccno)) {
$card = "Visa"; }
if (preg_match('/^\s*5[1-5]\d{2}[-\s]*\d{4}[-\s]*\d{4}[-\s]*\d{4}\s*$/',$ccno)) {
$card = "MC"; }
if (preg_match('/^\s*6011[-\s]*\d{4}[-\s]*\d{4}[-\s]*\d{4}\s*$/',$ccno)) {
$card = "Discover"; }
if (preg_match('/^\s*3[47](\d\s*){13}$/',$ccno)) {
$card = "AmEx"; }
if (preg_match('/^\s*3[068](\d\s*){12}$/',$ccno)) {
$card = Diners; }
# 2. Does the checksum work out?
# Get rid of none-digits
$ccno = preg_replace('/\D/','',$ccno);
$checksum = 0;
for ($i=strlen($ccno)-1; $i>=0 ; $i-=2) {
# Last digit, and alternate digits before it
$checksum += $ccno[$i];
# Other digits
if ($i) {
$digit = 2 * $ccno[$i-1];
$checksum += ($digit < 10) ? $digit : $digit-9;
}
}
return (array($card,$checksum%10 == 0 && $card != "",$checksum));
}
/* Notes
1. Debit cards - Maestro - 18 digits
http://web-usability-expert.com/2007/08/06/uk-debit-and-credit-card-validation/
2. Credit cards
http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CC70060A01B
*/
?>
Online booking starts with
https protocol rather that
http as you'll find if you use our booking systems. This is one of my few bits of code that I am *not* going to put in my "demo" directory for you to try out - as that would be starting to teach you insecure ways by example.
Our
PHP Techniques Workshop does cover aspects of accepting credit and debit cards online, and you can book
hotel rooms in Melksham and
public training course places via our sites. If you're looking for a private course, there are so many ways that we can tailor our training that we want to talk about your requirements before you book, so we don't have a completely automated, human intervention free, system.
The illustrations with this post show bedrooms 4 (top) and 3 (lower) at Well House Manor, where we offer accommodation for visitors to the town of Melksham. Our facilities are designed for the business traveller, but others are welcome too - all rooms are double or twin (but are usually let for single occupancy), there is internet access available 24 x 7, plenty of power points, large screen TVs with some 50 channels ... all rooms are en suite, there's tea, coffee and soft drinks available all day, every day ... and all these things which are often extras are included in the price, as is a breakfast of freshly squeezed orange juice, fruit, cereal, yoghurt, bread, toast and croissants, ham and cheese, jams and marmalade. (written 2008-10-14)
Associated topics are indexed as below, or enter http://melksh.am/nnnn for individual articles
Q806 - Regular Expression Cookbook [672] Keeping your regular expressions simple - (2006-04-05)
[1230] Commenting a Perl Regular Expression - (2007-06-12)
[1305] Regular expressions made easy - building from components - (2007-08-16)
[2165] Making Regular Expressions easy to read and maintain - (2009-05-10)
[2563] Efficient debugging of regular expressions - (2010-01-04)
[2608] Search and replace in Ruby - Ruby Regular Expressions - (2010-01-31)
[2702] First and last match with Regular Expressions - (2010-04-02)
[2727] Making a Lua program run more than 10 times faster - (2010-04-16)
[2804] Regular Expression Myths - (2010-06-13)
[3218] Matching a license plate or product code - Regular Expressions - (2011-03-28)
[3788] Getting more than a yes / no answer from a regular expression pattern match - (2012-06-30)
Q110 - Object Orientation and General technical topics - Programming Algorithms [202] Searching for numbers - (2005-02-04)
[227] Bellringing and Programming and Objects and Perl - (2005-02-25)
[642] How similar are two words - (2006-03-11)
[1157] Speed Networking - a great evening and how we arranged it - (2007-04-21)
[1187] Updating a page strictly every minute (PHP, Perl) - (2007-05-14)
[1391] Ordnance Survey Grid Reference to Latitude / Longitude - (2007-10-14)
[1949] Nuclear Physics comes to our web site - (2008-12-17)
[2189] Matching disparate referencing systems (MediaWiki, PHP, also Tcl) - (2009-05-19)
[2259] Grouping rows for a summary report - MySQL and PHP - (2009-06-27)
[2509] A life lesson from the accuracy of numbers in Excel and Lua - (2009-11-21)
[2586] And and Or illustrated by locks - (2010-01-17)
[2617] Comparing floating point numbers - a word of caution and a solution - (2010-02-01)
[2894] Sorting people by their names - (2010-07-29)
[2951] Lots of way of converting 3 letter month abbreviations to numbers - (2010-09-10)
[2993] Arrays v Lists - what is the difference, why use one or the other - (2010-10-10)
[3042] Least Common Ancestor - what is it, and a Least Common Ancestor algorithm implemented in Perl - (2010-11-11)
[3072] Finding elements common to many lists / arrays - (2010-11-26)
[3093] How many toilet rolls - hotel inventory and useage - (2010-12-18)
[3102] AND and OR operators - what is the difference between logical and bitwise varieties? - (2010-12-24)
[3451] Why would you want to use a Perl hash? - (2011-09-20)
[3620] Finding the total, average, minimum and maximum in a program - (2012-02-22)
[3662] Finding all the unique lines in a file, using Python or Perl - (2012-03-20)
[4325] Learning to program - what are algorithms and design patterns? - (2014-11-22)
[4401] Selecting RECENT and POPULAR news and trends for your web site users - (2015-01-19)
[4402] Finding sum, minimum, maximum and average in Python (and Ruby) - (2015-01-19)
[4410] A good example of recursion - a real use in Python - (2015-02-01)
[4652] Testing new algorithms in PHP - (2016-02-20)
[4656] Identifying the first and last records in a sequence - (2016-02-26)
[4707] Some gems from an introduction to Python - (2016-10-29)
H310 - PHP - Putting it all together [468] Stand alone PHP programs - (2005-10-18)
[687] Presentation, Business and Persistence layers in Perl and PHP - (2006-04-17)
[1716] Larger applications in PHP - (2008-07-22)
[1754] Upgrade from PHP 4 to PHP 5 - the TRY issue - (2008-08-15)
[1794] Refactoring - a PHP demo becomes a production page - (2008-09-12)
[1962] Index Card System for Game Characters in PHP - (2008-12-27)
[2275] Debugging multipage (session based) PHP applications - (2009-07-09)
[2635] A PHP example that lets your users edit content without HTML knowledge - (2010-02-14)
[2931] Syncronise - software, trains, and buses. Please! - (2010-08-22)
[3454] Your PHP website - how to factor and refactor to reduce growing pains - (2011-09-24)
A213 - Web Application Deployment - Commercial and Legal Aspects [142] Colour for access - (2004-12-06)
[259] Responding to spam - (2005-03-27)
[288] Colour blindness for web developers - (2005-04-22)
[320] Ordnance Survey - using a 'Get a map' - (2005-05-22)
[322] More maps - (2005-05-23)
[532] Copyright - how much can I legally copy? - (2005-12-17)
[746] Domain Listing Center and Domain Registry of America - (2006-06-06)
[759] Watch your Google profile - (2006-06-13)
[795] Remember a site's non-technical issues too - (2006-07-07)
[876] Making pages clearer - easy Disability Discrimination Act Compliance - (2006-09-23)
[994] Training on Cascading Style Sheets - (2006-12-17)
[1054] UK legal requirements for your commercial web site - (2007-01-27)
[1431] Getting the community on line - some basics - (2007-11-13)
[1485] Copyright and theft of images, bandwidth and members. - (2007-12-26)
[1486] Does anyone understand Lithuanian? - (2007-12-27)
[1506] Ongoing Image Copyright Issues, PHP and MySQL solutions - (2008-01-14)
[1747] Who is watching you? - (2008-08-10)
[1937] Getting hold of the wrong end of the stick - (2008-12-12)
[2140] Beware - giving copyright away when you upload a picture - Dogs Trust - (2009-04-25)
[2252] Leaping dog, Leaping horse, copyright of old masters - (2009-06-20)
[2592] Re-using our pictures - (2010-01-21)
[2686] Freedom of Information - consideration for web site designers - (2010-03-20)
[3016] The legal considerations of your web presence - revisited - (2010-10-26)
[3104] Catering in Syracuse, the Saigon Cafe, stolen images and Christmas - (2010-12-25)
[3168] Web Sites - Subject to Advertising Standards from 1st March - check your sites - (2011-02-13)
[3745] Legal change - You need to obtain user consent if you use cookies on your website - (2012-06-01)
[3746] Google Analytics and the new UK Cookie law - (2012-06-02)
[3747] An easy way to comply with the new cookie law if your site is well designed - (2012-06-02)
[4234] Change to Libel and Defamation laws from 1st January 2014 - (2013-12-31)
[4283] Can a legitimate forum post become illegal a year later? - (2014-07-11)
A212 - Web Application Deployment - Secure Service and Credit Cards [46] Near and far security - (2004-09-12)
[2097] PHP Course - for hobby / club / charity users. - (2009-03-22)
Some other Articles
Calling functions in C from your Lua script - a first HowToHow many cups of coffee?Lua Course, and the Wiltshire Countryside tooFormatting with a leading + / Lua and PerlValidating Credit Card NumbersJob applicationOxford in PicturesAlfred the GreatNext in the sequence - courses next year (2009)23:30 bookings and midnight checkins