Last active
June 12, 2024 07:19
-
-
Save ibrahimlawal/23816015596b5af511d27faa4f1794ca to your computer and use it in GitHub Desktop.
Validate card numbers using Regex and a Luhn Check
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Operations { | |
const PATTERN_AMERICAN_EXPRESS = "/^3[47][0-9]{13}$/"; | |
const PATTERN_DINERS_CLUB = "/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/"; | |
const PATTERN_DISCOVER = "/^6(?:011|5[0-9]{2})[0-9]{12}$/"; | |
const PATTERN_JCB = "/^(?:2131|1800|35[0-9]{3})[0-9]{11}$/"; | |
const PATTERN_MASTERCARD = "/^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/"; | |
const PATTERN_VERVE = "/^((506(0|1))|(507(8|9))|(6500))[0-9]{12,15}$/"; | |
const PATTERN_VISA = "/^4[0-9]{12}(?:[0-9]{3})?$/"; | |
public function can_be_string($var) | |
{ | |
return $var === null || is_scalar($var) || (is_object($var) && method_exists($var, '__toString')); | |
} | |
public function is_valid_luhn($number) | |
{ | |
$sumTable = [ | |
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], | |
[0, 2, 4, 6, 8, 1, 3, 5, 7, 9], | |
]; | |
$sum = 0; | |
$flip = 0; | |
for ($i = strlen($number) - 1; $i >= 0; $i--) { | |
$sum += $sumTable[$flip++ & 0x1][$number[$i]]; | |
} | |
return $sum % 10 === 0; | |
} | |
public function cardType($number) | |
{ | |
$cardtype = 'Unknown'; | |
// only values that can be converted to string can be checked | |
if (!$this->can_be_string($number)) { | |
return $cardtype; | |
} | |
$number = strval($number); | |
$number = preg_replace("/[^0-9]/", "", $number); | |
// only non-zero length strings can be checked | |
if (!strlen($number)) { | |
return $cardtype; | |
} | |
if (preg_match(Operations::PATTERN_MASTERCARD, $number)) { | |
$cardtype = 'mastercard'; | |
} elseif (preg_match(Operations::PATTERN_VERVE, $number)) { | |
$cardtype = 'verve'; | |
} elseif (preg_match(Operations::PATTERN_VISA, $number)) { | |
$cardtype = 'visa'; | |
} elseif (preg_match(Operations::PATTERN_DINERS_CLUB, $number)) { | |
$cardtype = 'Diners Club'; | |
} elseif (preg_match(Operations::PATTERN_DISCOVER, $number)) { | |
$cardtype = 'Discover'; | |
} elseif (preg_match(Operations::PATTERN_AMERICAN_EXPRESS, $number)) { | |
$cardtype = 'American Express'; | |
} elseif (preg_match(Operations::PATTERN_JCB, $number)) { | |
$cardtype = 'JCB'; | |
} | |
$cardtype = $this->is_valid_luhn($number) ? $cardtype : 'Unknown'; | |
return $cardtype; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment