当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在PHP中验证信用卡的最佳方法是什么?》经验,为你挑选了5个好方法。

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

现在我需要能够使用American Express,Discover,MasterCard和Visa的东西,但如果它也可以与其他类型一起使用可能会有所帮助.



1> Ray Hayes..:

验证卡号有三个部分:

    PATTERN - 是否与发行人模式匹配(例如VISA/Mastercard /等)

    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)

发现前缀= 6011,622126-622925,644-649,65,长度= 16,(Mod10)

等(前缀的详细列表)

校验

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

维基百科上描述的Luhn算法

维基百科链接上有许多实现的链接,包括PHP:

 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;

}
?>


此功能删除字符串中的所有非数字,因此卡号"FRED"有效.在调用此功能之前,请确保您已验证卡号仅有数字!
除了0之外的任何信用卡编号都是有效的
@BijuPDais正如文中所述 - 为了检查它是否真的存在,你可能需要成为一个商人,并且实际上试图为卡计费.许多行为(如酒店)收取费用,然后将少量退款到信用卡上.在所有验证方法中 - 这是对卡是否有效的唯一真实测试!

2> ConroyP..:

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

function check_cc($cc, $extra_check = false){
    $cards = array(
        "visa" => "(4\d{12}(?:\d{3})?)",
        "amex" => "(3[47]\d{13})",
        "jcb" => "(35[2-8][89]\d\d\d{10})",
        "maestro" => "((?:5020|5038|6304|6579|6761)\d{12}(?:\d\d)?)",
        "solo" => "((?:6334|6767)\d{12}(?:\d\d)?\d?)",
        "mastercard" => "(5[1-5]\d{14})",
        "switch" => "(?:(?:(?:4903|4905|4911|4936|6333|6759)\d{12})|(?:(?:564182|633110)\d{10})(\d\d)?\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 "
"; }

这给了我们

4111 1111 1111 1111 - Visa



3> PartialOrder..:

最好不要在最后验证代码.将卡信息直接发送到您的支付网关,然后处理他们的回复.如果你不先做Luhn检查,那么它可以帮助他们检测欺诈行为 - 让他们看到失败的尝试.


唯一的问题是每笔交易都有成本.它可能很小,但它会增加,如果有人通过您的系统运行大量欺诈性卡号,费用可能会变得无法控制.

4> Patrick Desj..:

PHP代码

function validateCC($cc_num, $type) {

    if($type == "American") {
    $denum = "American Express";
    } elseif($type == "Dinners") {
    $denum = "Diner's Club";
    } elseif($type == "Discover") {
    $denum = "Discover";
    } elseif($type == "Master") {
    $denum = "Master Card";
    } elseif($type == "Visa") {
    $denum = "Visa";
    }

    if($type == "American") {
    $pattern = "/^([34|37]{2})([0-9]{13})$/";//American Express
    if (preg_match($pattern,$cc_num)) {
    $verified = true;
    } else {
    $verified = false;
    }


    } elseif($type == "Dinners") {
    $pattern = "/^([30|36|38]{2})([0-9]{12})$/";//Diner's Club
    if (preg_match($pattern,$cc_num)) {
    $verified = true;
    } else {
    $verified = false;
    }


    } elseif($type == "Discover") {
    $pattern = "/^([6011]{4})([0-9]{12})$/";//Discover Card
    if (preg_match($pattern,$cc_num)) {
    $verified = true;
    } else {
    $verified = false;
    }


    } elseif($type == "Master") {
    $pattern = "/^([51|52|53|54|55]{2})([0-9]{14})$/";//Mastercard
    if (preg_match($pattern,$cc_num)) {
    $verified = true;
    } else {
    $verified = false;
    }


    } elseif($type == "Visa") {
    $pattern = "/^([4]{1})([0-9]{12,15})$/";//Visa
    if (preg_match($pattern,$cc_num)) {
    $verified = true;
    } else {
    $verified = false;
    }

    }

    if($verified == false) {
    //Do something here in case the validation fails
    echo "Credit card invalid. Please make sure that you entered a valid " . $denum . " credit card ";

    } else { //if it will pass...do something
    echo "Your " . $denum . " credit card is valid";
    }


}

用法

echo validateCC("1738292928284637", "Dinners");

更多理论信息可以在这里找到:

信用卡验证 - 检查数字

校验



5> jeeva..:

我们可以使用以下方法验证信用卡.它对我来说很完美.

protected function luhn($number)
{
    // Force the value to be a string as this method uses string functions.
    // Converting to an integer may pass PHP_INT_MAX and result in an error!
    $number = (string)$number;

    if (!ctype_digit($number)) {
        // Luhn can only be used on numbers!
        return FALSE;
    }

    // Check number length
    $length = strlen($number);

    // Checksum of the card number
    $checksum = 0;

    for ($i = $length - 1; $i >= 0; $i -= 2) {
        // Add up every 2nd digit, starting from the right
        $checksum += substr($number, $i, 1);
    }

    for ($i = $length - 2; $i >= 0; $i -= 2) {
        // Add up every 2nd digit doubled, starting from the right
        $double = substr($number, $i, 1) * 2;

        // Subtract 9 from the double where value is greater than 10
        $checksum += ($double >= 10) ? ($double - 9) : $double;
    }

    // If the checksum is a multiple of 10, the number is valid
    return ($checksum % 10 === 0);
}

protected function ValidCreditcard($number)
{
    $card_array = array(
        'default' => array(
            'length' => '13,14,15,16,17,18,19',
            'prefix' => '',
            'luhn' => TRUE,
        ),
        'american express' => array(
            'length' => '15',
            'prefix' => '3[47]',
            'luhn' => TRUE,
        ),
        'diners club' => array(
            'length' => '14,16',
            'prefix' => '36|55|30[0-5]',
            'luhn' => TRUE,
        ),
        'discover' => array(
            'length' => '16',
            'prefix' => '6(?:5|011)',
            'luhn' => TRUE,
        ),
        'jcb' => array(
            'length' => '15,16',
            'prefix' => '3|1800|2131',
            'luhn' => TRUE,
        ),
        'maestro' => array(
            'length' => '16,18',
            'prefix' => '50(?:20|38)|6(?:304|759)',
            'luhn' => TRUE,
        ),
        'mastercard' => array(
            'length' => '16',
            'prefix' => '5[1-5]',
            'luhn' => TRUE,
        ),
        'visa' => array(
            'length' => '13,16',
            'prefix' => '4',
            'luhn' => TRUE,
        ),
    );

    // Remove all non-digit characters from the number
    if (($number = preg_replace('/\D+/', '', $number)) === '')
        return FALSE;

    // Use the default type
    $type = 'default';

    $cards = $card_array;

    // Check card type
    $type = strtolower($type);

    if (!isset($cards[$type]))
        return FALSE;

    // Check card number length
    $length = strlen($number);

    // Validate the card length by the card type
    if (!in_array($length, preg_split('/\D+/', $cards[$type]['length'])))
        return FALSE;

    // Check card number prefix
    if (!preg_match('/^' . $cards[$type]['prefix'] . '/', $number))
        return FALSE;

    // No Luhn check required
    if ($cards[$type]['luhn'] == FALSE)
        return TRUE;

    return $this->luhn($number);

}

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有