Archive for 'Validation'

Validate Email address

Whenever you are doing form processing, it is handy to have an email validation function.

Here is one I found and tweaked a bit. Has given me a lot of good mileage!

function check_email_address($email) {
    if (!ereg("^[^@]{1,64}@[^@]{1,255}$", $email)) {
      return false;
    }
    $email_array = explode("@", $email);
    $local_array = explode(".", $email_array[0]);
    for ($i = 0; $i < sizeof($local_array); $i++) {
      if (!ereg("^(([A-Za-z0-9!#$%&'*+/=?^_`{|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$", $local_array[$i])) {
        return false;
      }
    }
    if (!ereg("^\[?[0-9\.]+\]?$", $email_array[1])) { 
      $domain_array = explode(".", $email_array[1]);
      if (sizeof($domain_array) < 2) {
        return false; 
      }
      for ($i = 0; $i < sizeof($domain_array); $i++) {
        if (!ereg("^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$", $domain_array[$i])) {
          return false;
        }
      }
    }
    return true;
  }

Credit Card validation

At one point or another everyone gets to a project where they’ve got to get credit card details from a client to process a payment. The security aspect of this is a whole book on it’s own, but that’s not the point of this post. I’ve always been fascinated how ID numbers (or social security numbers) work and how they can be validated.

I decided a few months ago to do some research into writing a simple credit card verification function. Obviously this doesn’t cater for the fact that it might be a stolen or canceled card, but it will give you an idea if the credit card number, validation numbers and expiration date are correct.

First I started by finding out what the patterns are for the varies credit card companies. I found this on Sitepoint. Although he has a complete class on that site, what is the fun in it all if you don’t write your own code to understand it a bit better?

Apart from passing the Mod 10 algorithm, each credit card company has further checks:

  • Mastercard: Must have a prefix of 51 to 55, and must be 16 digits in length
  • Visa: Must have a prefix of 4, and must be either 13 or 16 digits in length
  • American Express: Must have a prefix of 34 or 37, and must be 15 digits in length
  • Diners Club: Must have a prefix of 300 to 305, 36, or 38, and must be 14 digits in length
  • Discover: Must have a prefix of 6011, and must be 16 digits in length
  • JCB: Must have a prefix of 3, 1800, or 2131, and must be either 15 or 16 digits in length

Ok, so what is the Mod 10 Algorithm? It is a algorithm that will be able to spot errors of the digits in the credit card number. It’s not specifically made for credit card numbers, but has got other uses. Check out Wikipedia.org for more information. To explain it, let’s look at the steps thereof.

Step of the Mod 10 Algorithm for the number 4111111111111111:

  1. You start off by reversing the number so it becomes 1111111111111114
  2. Now multiply each 2nd digit by 2
    1111111111111114 => 1212121212121218
  3. Add all the resulting digits together
    1+2+1+2+1+2+1+2+1+2+1+2+1+2+1+8 = 30
  4. Take that number and divide it by 10. It goes 3 times into 30 with 0 remainder. If the remainder is 0 that means it passes.

This is also called a MOD operator. The MOD operator divides a number by another number and then gives you the remainder.

Those are the 2 tests a credit card number must pass. First checking if it’s got correct digits according to the type of credit card and then checking if the digits pass the Mod 10 algorithm.

Let’s look at the code for this.

function mod10_check($number) { 
    /* validate mod10 check on the number */
    $rcode = strrev($number);
    $csum = 0;
    for ($i = 0; $i < strlen($rcode); $i++) {
      $current_num = intval($rcode[$i]);
      if($i & 1) {  /*every 2nd digit - odd*/
        $current_num *= 2;
      }
 
      /* split the digits and add up */
      $csum += $current_num % 10; 
      if ($current_num >  9) {
        $csum += 1;
      }
    }
 
    if ($csum % 10 == 0) {
      return true;
    } else {
      return false;
    }
  }
 
  function validate_ccnumber($ccnumber) {
    /* validate; return card type if valid. */
    $c_type = "";
    $c_reg = array(
      "/^4\d{12}(\d\d\d){0,1}$/" => "visa",
      "/^5[12345]\d{14}$/" => "mastercard",
      "/^6011\d{12}$/" => "discover",
      "/^30[012345]\d{11}$/" => "diners",
      "/^3[68]\d{12}$/" => "diners",
    );
 
    foreach ($c_reg as $reg => $type) {
      if (preg_match($reg, $ccnumber)) {
        $c_type = $type;
        break;
      }
    }
 
    if (!$c_type) {
      //card type not found
      return false;
     }
 
    if (mod10_check($ccnumber)) {
      return $c_type;
    } else {
      return false;
    }
  }

I’ve split this up into 2 functions, namely mod10_check and validate_ccnumber. You can incorporate them into one function, I just found it easier this way so that I can reuse mod10_check later on separately.

So first I make use of regular expressions to determine which card type it is. I’ve only made use of the well known cards here, but it is easy to add additional card regular expressions as you see fit.

If the card type is found and checks out okay, we do the final check which is the Mod10 algorithm. If that also checks out, we return the card type from the function.

Sample usage:

if ($result = validate_ccnumber('4111111111111111')) { 
  echo $result;
} else {
  echo "invalid";
}