信用卡号码规则和校验方法(含PHP代码)(转自《PHP 5 in Practice中文版》)

11.5  信用卡号码

商业站点需要处理信用卡号码。信用卡公司已经在卡号里建立了校验体系。在把信用卡号码标准化为不包含空格的数字字符串之后,可以进行两方面的检验。

首先,不同信用卡公司遵循特定的编号规则。

n   Visa:以4开头,共有13位或16位数字。

n   MasterCard:以51~56开头,共有16位数字。

n   American Express:以34或37开头,共有15位数字。

n   Discover:以6011开头,共有16位数字。

另外,所有卡号还要遵循称为“Mod 10”的算法,它可以用来判断某个号码是否属于有效的信用卡号码。它的工作方式是这样的:首先颠倒数字的次序,接着每隔一个数字把数字乘以2,然后把所有 的数字加起来;但如果相乘结果大于等于10,就要把这个结果的个位和十位的数字加起来。例如数字7,乘以2以后是14,所以它对应的数字应该是 1+4=5。在所有数字相加之后,其结果应该能够被10整除。上述这些规则都写入了程序清单11.5.1包含的函数里。

程序清单11.5.1  信用卡号码函数库

  1. <?php
  2. // A function that will accept and clean up CC numbers
  3. function standardize_credit($num) {
  4.      // Remove all non-digits from the string
  5.      return preg_replace('/[^0-9]/'''$num);
  6. }
  7. // A function to check the validity of a CC number
  8. // It must be provided with the number itself, as well as
  9. // a character specifying the type of CC:
  10. // m = Mastercard, v = Visa, d = Discover, a = American Express
  11. function validate_credit($num$type) {
  12.      // First perform the CC specific tests:
  13.      // Store a few evaluations we will need often:
  14.      $len = strlen($num);
  15.      $d2 = substr($num,0,2);
  16.      // If Visa must start with a 4, and be 13 or 16 digits long:
  17.      if ( (($type == 'v') && (($num{0} != 4) ||
  18.                    !(($len == 13) || ($len == 16)))) ||
  19.      // If Mastercard, start with 51-56, and be 16 digits long:
  20.            (($type == 'm') && (($d2 < 51) ||
  21.                     ($d2 > 56) || ($len != 16))) ||
  22.      // If American Express, start with 34 or 37, 15 digits long:
  23.            (($type == 'a') && (!(($d2 == 34) ||
  24.                     ($d2 == 37)) || ($len != 15))) ||
  25.      // If Discover: start with 6011 and 16 digits long
  26.            (($type == 'd') && ((substr($num,0,4) != 6011) ||
  27.                     ($len != 16))) ) {
  28.            // Invalid card:
  29.            return false;
  30.      }
  31.      // If we are still here, then time to manipulate and do the Mod 10
  32.      // algorithm. First break the number into an array of characters:
  33.      $digits = str_split($num);
  34.      // Now reverse it:
  35.      $digits = array_reverse($digits);
  36.      // Double every other digit:
  37.      foreach(range(1, count($digits) - 1, 2) as $x) {
  38.           // Double it
  39.           $digits[$x] *= 2;
  40.           // If this is now over 10, go ahead and add its digits, easier since
  41.           // the first digit will always be 1
  42.           if ($digits[$x] > 9) {
  43.                $digits[$x] = ($digits[$x] - 10) + 1;
  44.           }
  45.      }
  46.      // Now, add all this values together to get the checksum
  47.      $checksum = array_sum($digits);
  48.      // If this was divisible by 10, then true, else it's invalid
  49.      return (($checksum % 10) == 0) ? true : false;
  50. }
  51. // Check various credit card numbers:
  52. $nums = array(
  53.      '344 2345 3466 4577' => 'a''3794 2345 3466 4577' => 'a',
  54.      '4938748398324' => 'v''4123-1234-5342' => 'v',
  55.      '51847293 84567434' => 'm''5723x2345x2345x6161' => 'm',
  56.      '6011 6011 6011 6011' => 'd''6012 392563242423' => 'd',
  57.      );
  58. foreach ($nums as $num => $type) {
  59.      $st = standardize_credit($num);
  60.      $valid = validate_credit($st$type);
  61.      $output = $valid ? 'Valid' : 'Invalid';
  62.      echo "<p>{$st} - {$type} = {$output}</p>/n";
  63. }
  64. ?>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值