首页 文章

我应该使用CreditCardAttribute来验证信用卡号吗?

提问于
浏览
8

我应该使用微软的CreditCardAttribute来验证信用卡号码吗?

[Required, CreditCard]
public string CreditCardNumber { get; set; }

或者我应该让支付网关处理它,还是做其他事情?在发现一些客户无法使用他们的信用卡信息提交付款后,我问这个问题 . 幸运的是,我能够与其中一个客户合作,并发现他们的Visa卡在删除 CreditCardAttribute 后没有遇到任何问题 .

在某种程度上,这个问题是修辞性的,但我想从其他开发人员的想法和经验中受益,并让其他开发人员通过提出问题来了解使用 CreditCardAttribute 的风险 .

2 回答

  • 2

    我认为找到这个的最好方法是简单地测试它:

    using System;
    using System.Linq;
    using System.Text;
    using System.IO;
    
    namespace SO
    {
        class Program
        {
            static void Main(string[] args)
            {
                string[] cards = new string[] {
                    //http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
                    "378282246310005",  // American Express
                    "4012888888881881", // Visa
                    "6011111111111117", // Discover
                    "4222222222222", // Visa
                    "76009244561", // Dankort (PBS)
                    "5019717010103742", // Dakort (PBS) 
                    "6331101999990016", // Switch/Solo (Paymentech)
                    "30569309025904", // Diners Club 
                    //http://www.getcreditcardnumbers.com/
                    "5147004213414803", // Mastercard
                    "6011491706918120", // Discover
                    "379616680189541", // American Express
                    "4916111026621797", // Visa
                };
    
                foreach (string card in cards)
                {
                    Console.WriteLine(IsValid(card));
                }
    
                Console.ReadLine();
            }
    
            public static bool IsValid(object value)
            {
                if (value == null)
                {
                    return true;
                }
    
                string ccValue = value as string;
                if (ccValue == null)
                {
                    return false;
                }
                ccValue = ccValue.Replace("-", "");
                ccValue = ccValue.Replace(" ", "");
    
                int checksum = 0;
                bool evenDigit = false;
    
                // http://www.beachnet.com/~hstiles/cardtype.html
                foreach (char digit in ccValue.Reverse())
                {
                    if (digit < '0' || digit > '9')
                    {
                        return false;
                    }
    
                    int digitValue = (digit - '0') * (evenDigit ? 2 : 1);
                    evenDigit = !evenDigit;
    
                    while (digitValue > 0)
                    {
                        checksum += digitValue % 10;
                        digitValue /= 10;
                    }
                }
    
                return (checksum % 10) == 0;
            }
        }
    }
    

    IsValid方法来自原始的C#CreditCardAttribute类 . 12个数字中有1个失败:

    True
            True
            True
            True
            False //"76009244561", // Dankort (PBS)
            True
            True
            True
            True
            True
            True
            True
    

    那么,你应该使用它吗?不,显然它没有检测到所有数字 . 虽然你可以拿他们的代码并改进它!

  • 4

    在信用卡attribute后面的code中,它只是执行Luhn检查 .

    所有支付卡(*)目前都遵循ISO/IEC/7812标准,其最后一位数字为luhn校验位 .

    这个luhn检查仅用于防止转换错误 . 在将卡号提交给支付网关之前,它可用作健全性检查,但不适合绝对验证号码是否是有效的卡号 .

    有效卡号范围每月更改一次,绝对验证号码的唯一方法是通过支付网关对其进行验证 . 如果仅尝试验证卡(而不是对其进行充电),则应使用零值“仅授权”样式检查 .

    (*)唯一的例外是中国的卡片类型,即中国银联
    (历史上还有一个大型俱乐部'enRoute'品牌,于1992年被撤销)

相关问题