<?php
	/* 
	** File: validateCard
	** Description: Function for validating a credit card number
	** Version: $Revision: 1.2 $
	** Created: 12/20/1999
	** Author: Leon Atkinson
	** Email: leon@clearink.com
	** CVS Author: $Author: leon $
	** Last Revised: $Date: 1999/12/21 16:51:16 $
	**
	** Copyright (c) 1999 Working Dogs. All rights reserved. 
	*/

	/*
	** Ensure that this function isn't included twice
	*/

	$included_flag = 'INCLUDE_' . basename(__FILE__);
	
	if(defined($included_flag))
		//if this module has been included already, then the
		//constant will be defined.  Note the unusual use of
		//the return statement here.  Control will return to
		//the file that included it.
		return;
	
	define($included_flag, TRUE);	


	/*
	** Function: validateCard
	** Input: STRING card
	** Ouput: STRING/BOOLEAN
	** Description: a card is tested for being a recognized type
	** and for passing the MOD 10 algorithm.
	*/
	function validateCard($card)
	{ 	
		//remove non-numbers
		$card = ereg_replace('[^0-9]','', $card);

		/*
		** determine card type
		*/
		
		if(ereg('^3[4|7]', $card) AND (strlen($card) == 15))
		{
			//American Express
			//Starts with 34 or 37
			//15 numbers long
			$type = 'AMER';
		}
		elseif(ereg('^4', $card ) AND 
			((strlen($card) == 13) OR (strlen($card) == 16)))
		{
			//Visa
			//Starts with 4
			//13 or 16 numbers long
			$type = 'VISA';
		}
		elseif(ereg('^5[1-5]', $card) AND (strlen($card) == 16))
		{
			//MasterCard
			//Starts with 51,52,53,54,55
			//16 numbers long
			$type = 'MAST';
		}
		elseif(ereg('^6011', $card) AND (strlen($card) == 16))
		{
			//Discover
			//Starts with 6011
			//16 numbers long
			$type = "DISC";
		}
		else
		{
			return(FALSE);
		}
	
		/*
		** compute MOD 10 check
		**
		** 1. Start at last digit and work backwards
		** 2. Odd digits to total
		** 3. Multiply even digits by 2 and add digits to total
		** 4. If sum is divisible by 10, everything's OK
		*/
		$check = 0;
		$mode = "add";
		for($i=strlen($card)-1; $i >= 0; $i--)
		{
			//alternate between doubling 
			if($mode == "double")
			{
				//double digit
				$sum = strval($card[$i] * 2);
				
				//add digits to total
				$check += intval($sum[0]);
				if(intval($sum) > 10)
				{
					$check += intval($sum[1]);
				}
				$mode = "add";
			}
			else
			{
				//add digit to total
				$check += intval($card[$i]);
				$mode = "double";
			}
		}


		/*
		** Test the check
		*/
		if($check % 10)
		{
			//not divisible by 10, so it's a bad card
			return(FALSE);
		}
		else
		{
			//everything checks out
			return($type);
		}
	} 
?>