在PHP中验证信用卡的最佳方式是什么?

给定一个信用卡号码并且没有附加信息,PHP中确定它是否是有效数字的最佳方法是什么?

现在我需要一些能够与美国运通,Discover,MasterCard和Visa合作的东西,但如果它也可以与其他类型一起使用,它可能会有所帮助。


验证卡号有三个部分:

  • PATTERN - 它是否符合发行者模式(例如VISA /万事达卡等)
  • CHECKSUM - 它是否实际检查总和(例如,在“34”之后不只是13个随机数字,使其成为AMEX卡号)
  • 真的存在 - 它实际上是否有关联的帐户(如果没有商家帐户,您不太可能获得此帐户)
  • 模式

  • MASTERCARD前缀= 51-55,长度= 16(Mod10校验和)
  • VISA前缀= 4,长度= 13或16(Mod10)
  • AMEX前缀= 34或37,长度= 15(Mod10)
  • Diners Club / Carte Prefix = 300-305,36或38,长度= 14(Mod10)
  • Discover Prefix = 6011,622126-622925,644-649,65,Length = 16,(Mod10)
  • 等等(前缀的详细列表)
  • 校验

    大多数卡片使用Luhn算法进行校验和:

    在维基百科上描述的Luhn算法

    Wikipedia链接上有很多实现的链接,包括PHP:

    <?
    /* Luhn algorithm number checker - (c) 2005-2008 shaman - www.planzero.org *
     * This code has been released into the public domain, however please      *
     * give credit to the original author where possible.                      */
    
    function luhn_check($number) {
    
      // Strip any non-digits (useful for credit card numbers with spaces and hyphens)
      $number=preg_replace('/D/', '', $number);
    
      // Set the string length and parity
      $number_length=strlen($number);
      $parity=$number_length % 2;
    
      // Loop through each digit and do the maths
      $total=0;
      for ($i=0; $i<$number_length; $i++) {
        $digit=$number[$i];
        // Multiply alternate digits by two
        if ($i % 2 == $parity) {
          $digit*=2;
          // If the sum is two digits, add them together (in effect)
          if ($digit > 9) {
            $digit-=9;
          }
        }
        // Total up the digits
        $total+=$digit;
      }
    
      // If the total mod 10 equals 0, the number is valid
      return ($total % 10 == 0) ? TRUE : FALSE;
    
    }
    ?>
    

    从10个正则表达式中你不能没有在PHP中生活:

    function check_cc($cc, $extra_check = false){
        $cards = array(
            "visa" => "(4d{12}(?:d{3})?)",
            "amex" => "(3[47]d{13})",
            "jcb" => "(35[2-8][89]ddd{10})",
            "maestro" => "((?:5020|5038|6304|6579|6761)d{12}(?:dd)?)",
            "solo" => "((?:6334|6767)d{12}(?:dd)?d?)",
            "mastercard" => "(5[1-5]d{14})",
            "switch" => "(?:(?:(?:4903|4905|4911|4936|6333|6759)d{12})|(?:(?:564182|633110)d{10})(dd)?d?)",
        );
        $names = array("Visa", "American Express", "JCB", "Maestro", "Solo", "Mastercard", "Switch");
        $matches = array();
        $pattern = "#^(?:".implode("|", $cards).")$#";
        $result = preg_match($pattern, str_replace(" ", "", $cc), $matches);
        if($extra_check && $result > 0){
            $result = (validatecard($cc))?1:0;
        }
        return ($result>0)?$names[sizeof($matches)-2]:false;
    }
    

    示例输入:

    $cards = array(
        "4111 1111 1111 1111",
    );
    
    foreach($cards as $c){
        $check = check_cc($c, true);
        if($check!==false)
            echo $c." - ".$check;
        else
            echo "$c - Not a match";
        echo "<br/>";
    }
    

    这给了我们

    4111 1111 1111 1111 - Visa
    

    最好不要在代码中进行验证。 将卡信息发送到您的支付网关,然后处理他们的回复。 它可以帮助他们发现欺诈行为,如果你没有做任何事情,比如Luhn先检查 - 让他们看到失败的尝试。

    链接地址: http://www.djcxy.com/p/12205.html

    上一篇: What is the best way to validate a credit card in PHP?

    下一篇: What is an efficient way to match n items with corresponding n items