【问题标题】:How to determine which number in a series is the invalid credit card number如何确定系列中的哪个号码是无效的信用卡号
【发布时间】:2011-12-25 19:09:46
【问题描述】:

我需要有关信用卡验证脚本的帮助。我已经弄清楚如何确定信用卡是否有效/无效,但我需要的是:

如果有人输入了无效的信用卡号,有没有办法确定哪个号码无效?

这是我当前确定卡是否有效/无效的代码:

function validateCreditcard_number($credit_card_number) {
    //Get the first digit
    $firstnumber = substr($credit_card_number, 0, 1);
    //Make sure it is the correct amount of digits. Account for dashes being present.
    switch ($firstnumber) {
        case 3:
            if (!preg_match('/^3\d{3}[ \-]?\d{6}[ \-]?\d{5}$/', $credit_card_number)) {
               return '<li>This is not a valid American Express card number. Please use a different credit/debit card or re-enter your credit/debit card details.</li>';
            }
            break;
        case 4:
            if (!preg_match('/^4\d{3}[ \-]?\d{4}[ \-]?\d{4}[ \-]?\d{4}$/', $credit_card_number)) {
                return '<li>This is not a valid Visa card number. Please use a different credit/debit card or re-enter your credit/debit card details.</li>';
            }
            break;
        case 5:
            if (!preg_match('/^5\d{3}[ \-]?\d{4}[ \-]?\d{4}[ \-]?\d{4}$/', $credit_card_number)) {
                 return '<li>This is not a valid MasterCard card number. Please use a different credit/debit card or re-enter your credit/debit card details.</li>';
            }
            break;
        case 6:
            if (!preg_match('/^6011[ \-]?\d{4}[ \-]?\d{4}[ \-]?\d{4}$/', $credit_card_number)) {
                return '<li>This is not a valid Discover card number. Please use a different credit/debit card or re-enter your credit/debit card details.</li>';
            }
            break;
        default:
            return '<li>This is not a valid credit card number. Please use a different credit/debit card or re-enter your credit/debit card details.</li>';
    } //END Switch statement

    //Luhn Algorithm
    $credit_card_number = str_replace('.', '', $credit_card_number);
    $credit_card_number = str_replace('-', '', $credit_card_number);
    $credit_card_number = str_replace(' ', '', $credit_card_number);
    $map = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                0, 2, 4, 6, 8, 1, 3, 5, 7, 9);
    $sum = 0;
    $last = strlen($credit_card_number) - 1;

    for ($i = 0; $i <= $last; $i++) {
        $sum += $map[$credit_card_number[$last - $i] + ($i & 1) * 10];
    }

    if ($sum % 10 != 0) {
       return '<li>This is not a valid credit card number. Please use a different credit/debit card or re-enter your credit/debit card details.</li>';
    } else {
       //If we made it this far the credit card number is in a valid format
       return 'This is a valid credit card number' ;
    }

} //END validateCreditcard_number

【问题讨论】:

  • 就个人而言,我永远不会去向用户解释为什么信用卡无效。信用卡的真正拥有者会自己意识到自己的错误。有人试图获得免费的东西,只会被你的精确指示所怂恿,说明什么是不正确的。
  • 即使可以,为什么要这样做?
  • @three3,符合有效信用卡格式的号码和实际有效的信用卡号码之间存在很大差异。我同意 Kai - 您最好使用支付网关或其他提供商来确定帐户是否有效。 stackoverflow.com/questions/174730/… 有一些很好的正则表达式和其他提示(尽管在 PHP 中)。
  • @KenWhite 你完全错了,这不是 CC # 的工作方式。很多cmets认为这是不安全的。这是一个简单的校验和,用于判断 CC 是否可能有效。 如果卡不是真的,那没关系。 CC 仍然需要点击支付网关,名称/到期/CSC 值仍然必须匹配。生成“有效”的信用卡号码非常容易。不可猜测的数字不是 CC 安全性的一部分,否则上述算法会使它们完全失效。想想人们,别再评论这种做法的安全性了,说这话很傻。
  • 后续评论。不,不可能知道哪个号码导致验证失败,因为任何后续号码都可能改变 CC # 的有效性。 IE,如果第 8 位“不正确”,则可以更改第 12 位以进行补偿。没有“一个”数字负责使 CC 无效,它是所有数字的总和。这就是重点。

标签: php javascript validation credit-card


【解决方案1】:

如果不假设第一个数字是正确的,您可能会走很长一段路。就目前而言,如果有人将其签证的第一个第一个号码输入为3 而不是4,则会被告知他们正在输入无效的美国运通卡。从可用性的角度来看,这是残酷的。如果信用卡号无效,那就是无效的。除非他们从另一个下拉列表中明确选择美国运通,否则这不是无效的美国运通。

除了那小小的改进之外,您所要求的都是不可能的。 mod10 校验和算法无法告诉您哪个数字不正确。

为了解释原因,请考虑以下简化场景:

  • 我有 5 位数字,我不知道它们是什么
  • 5位数字之和为50
  • 以下数字之一是非一的

下列哪个数字不正确?

9 + 11 + 8 + 9 + 12 = 49

无法判断。它可以是这些数字中的任何,它们中的任何一个都可能偏离-1。但这并不能开始描述我们的麻烦。我告诉过你,只有一个数字是错误的。在你的情况下,你不知道有多少是错的。一个数字可能会偏离 -2,而另一个图像可能会偏离 +1。从字面上看,有无数个“错误”状态。也许所有五个数字都错了!也许正确的 5 个数字是 0 0 0 0 50。这是您在使用 mod10/Luhn 验证时面临的问题。绝对不可能分辨出哪些数字/数字是/不正确的。

您在回答另一个答案时询问是否有其他算法来判断单个数字是否不正确;这没有任何意义。 Luhn 是算法,不管你喜不喜欢。这些数字不是为适应任何其他算法而生成的,而且在整个世界都在使用该算法后,您也无法更改该算法。


作为不相关的批评,您的函数不应返回人类可读的错误消息/成功消息。这是一种可怕的做法,会导致无法维护、无法本地化的应用程序。

【讨论】:

    【解决方案2】:

    Luhn 校验和无法检测哪个数字不正确,它只能检测一位数错误和一些多位错误。完全有可能输错两位数字并得到一个具有有效校验和的数字。

    【讨论】:

    • 还有其他算法可以吗?
    • @three3 当然...但它不用于/部分信用卡号码;卢恩是。就是这样。
    • @three3 - 为什么不改进错误 UI 以提示用户重新检查并重新提交新号码?
    【解决方案3】:

    你不能。信用卡号有一个校验和(错误检查代码),允许检测错误,但它们没有任何error correction code.

    【讨论】:

    • 维基百科文章 Bank Card Number 列出了有效长度、IIN 编号以及使用的验证(“错误检测”)(如果有)。
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 2013-02-07
    • 2016-09-18
    • 2013-11-23
    • 2013-07-23
    • 1970-01-01
    • 2018-07-10
    • 2022-01-12
    相关资源
    最近更新 更多