PHP实现信用卡号校验与有效期验证

小林子
小林子
发布时间:2026-10-14| 5人浏览过
原创

在接入支付渠道时,对银行卡号进行本地预校验能有效降低无效请求。本文将展示一个PHP函数,支持主流信用卡的BIN段识别、长度检查、Luhn算法校验及有效期判断。

功能与原理说明

完整的信用卡验证通常包含三个核心步骤:首先是格式与长度的初步筛查,根据国际标准化组织(ISO/IEC 7812)标准,不同发卡机构的卡号具有特定的开头数字和固定长度;其次是数学逻辑校验,业界普遍采用Luhn算法检测输入错误;最后是当前状态的确认,即检查卡片是否仍在有效期内。

第1步:定义验证函数入口与预处理

目的:获取原始输入,清洗非数字字符,为后续逻辑处理提供干净的字符串。

  • 函数命名:PIPHP_ValidateCC
  • 参数说明:
    • $number:字符串形式的信用卡号。
    • $expiry:有效期,格式支持MM/YY或纯数字MMYY。
  • 清洗操作:使用正则表达式/[^\d]/移除所有非数字字符。
// 提取纯数字的卡号
$number = preg_replace('/[^\d]/', '', $number);
// 提取纯数字的有效期
$expiry = preg_replace('/[^\d]/', '', $expiry);

第2步:发卡机构识别与长度校验

目的:根据卡号的前4位数字(BIN/IIN范围),匹配支持的银行网络,并拒绝长度不符的卡号。

以下是常见卡段的识别规则:

  • Diners Club:3000-3059, 3600-3699, 3800-3889(要求长度14位)
  • JCB:3088-3094, 3096-3102, 3112-3120, 3158-3159, 3337-3349, 3528-3589(要求长度16位)
  • American Express:3400-3499, 3700-3799(要求长度15位)
  • Visa:4000-4999(允许长度13位或16位)
  • MasterCard:5100-5599(要求长度16位)
  • Discover/Carte Blanche/BankCard等:根据特定区间判断

若卡号不在上述范围内,或对应的长度条件不满足,则直接返回 FALSE。

第3步:执行Luhn算法验证

目的:通过加权求和并取模运算,确保输入的卡号符合国际标准,排除偶然录入错误。

  1. 从右向左数(偶数位加奇数位,具体取决于起始索引计算)。代码中通过循环变量 $j 分别处理基数和偶数位。
  2. 对偶数位置上的数字乘以2,若结果大于等于10,则减去9(等价于各位数字之和)。
  3. 将所有数字累加得到 $chksum。
  4. 若 $chksum % 10 不为0,则卡号无效。

第4步:有效期状态检查

目的:防止已过期但仍符合算法校验的旧卡号被使用。

  • 将解析后的月份作为月份参数,当年当年的最后一天作为日期参数,创建时间戳。
  • 如果该时间点早于当前服务器时间(time()),说明已过期,返回 FALSE。

完整源码参考

<?php
// 测试数据示例
$card  = "4567 1234 5678 9101";
$exp  = "06/11";

echo "Validating: $card : $exp<br>";
$result = PIPHP_ValidateCC($card, $exp);
if ($result != FALSE) {
    echo "Card Validated Successfully";
} else {
    echo "Card did not validate";
}

function PIPHP_ValidateCC($number, $expiry)
{
    // 清理非数字字符
    $number = preg_replace('/[^\d]/', '', $number);
    $expiry = preg_replace('/[^\d]/', '', $expiry);
    
    // 提取前4位用于识别发卡机构
    $left  = substr($number, 0, 4);
    $cclen = strlen($number);
    $chksum = 0;
    
    // --- 发卡机构逻辑 ---
    // Diners Club (Len 14)
    if (($left >= 3000) && ($left <= 3059) ||
        ($left >= 3600) && ($left <= 3699) ||
        ($left >= 3800) && ($left <= 3889))
       if ($cclen != 14) return FALSE;
    
    // JCB (Len 16)
    if (($left >= 3088) && ($left <= 3094) ||
        ($left >= 3096) && ($left <= 3102) ||
        ($left >= 3112) && ($left <= 3120) ||
        ($left >= 3158) && ($left <= 3159) ||
        ($left >= 3337) && ($left <= 3349) ||
        ($left >= 3528) && ($left <= 3589))
       if ($cclen != 16) return FALSE;
    
    // American Express (Len 15)
    elseif (($left >= 3400) && ($left <= 3499) ||
          ($left >= 3700) && ($left <= 3799))
       if ($cclen != 15) return FALSE;
    
    // Carte Blanche (Len 14)
    elseif (($left >= 3890) && ($left <= 3899))
       if ($cclen != 14) return FALSE;
    
    // Visa (Len 13 or 16)
    elseif (($left >= 4000) && ($left <= 4999))
       if ($cclen != 13 && $cclen != 16) return FALSE;
    
    // MasterCard (Len 16)
    elseif (($left >= 5100) && ($left <= 5599))
       if ($cclen != 16) return FALSE;
    
    // Australian BankCard (Len 16)
    elseif ($left == 5610)
       if ($cclen != 16) return FALSE;
    
    // Discover (Len 16)
    elseif ($left == 6011)
       if ($cclen != 16) return FALSE;
    
    // 未知类型
    else return FALSE;

    // --- Luhn 算法校验 ---
    for ($j = 1 - ($cclen % 2); $j < $cclen; $j += 2)
       $chksum += substr($number, $j, 1);
    
    for ($j = $cclen % 2; $j < $cclen; $j += 2)
    {
       $d = substr($number, $j, 1) * 2;
       $chksum += $d < 10 ? $d : $d - 9;
    }
    
    if ($chksum % 10 != 0) return FALSE;

    // --- 有效期判断 ---
    // 注意:该部分依赖服务器所在时区及年份逻辑,对于测试环境有效,生产环境建议由支付网关确认
    $expiry_month = substr($expiry, 0, 2);
    $expiry_year  = substr($expiry, 2, 2);
    
    // 构建当月最后一天的时间戳进行比较
    if (@mktime(0, 0, 0, $expiry_month, date("t", mktime(0,0,0,$expiry_month,1,$expiry_year)), $expiry_year) < time()) 
        return FALSE;

    return TRUE;
}
?>

注意事项

  1. 安全性:本地JS或PHP脚本只能进行格式校验。真实的资金交易必须依赖银行或第三方支付网关(如Stripe、支付宝、银联)的异步回调来确认卡片真伪及余额。
  2. 兼容性:代码中包含的逻辑(如 mktime 的使用)假设了较新的PHP版本特性,旧版本环境中可能需要调整日期的构造方式。

以上就是利用PHP实现信用卡通用规则验证的详细内容,更多关于PHP程序设计的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。