信用卡类型和验证

Posted

技术标签:

【中文标题】信用卡类型和验证【英文标题】:Credit card type and validation 【发布时间】:2013-12-21 02:14:56 【问题描述】:

我想运行一个程序,该程序可以根据输入的号码确定信用卡号码的验证和类型。编译器显示我的编码中有错误的通知,但我无法检测到它在哪里。该程序也无法运行。下面是代码,

    import java.util.*;

    public class CreditCard 

        public static void main(String args[]) 
                String CType;(String number) 
                    if (number.startsWith("4"))
                        return "Visa";
                    else if (number.startsWith("5"))
                        return "MasterCard";
                    else if (number.startsWith("6"))
                        return "Discover";
                    else if (number.startsWith("37"))
                        return "American Express";
                    else
                        return "Unknown type";
                ;
            Scanner input = new Scanner(System.in);

            System.out.println("Enter a credit card number: ");
            long number = input.nextLong();

            long total = sumOfEvenPlaces(number) + (sumOfOddPlaces(number)*2);

            if (isValid(total)) 
                System.out.println("The "+CType+" card number is valid");
             else 
                System.out.println("The "+CType+" card number is invalid.");
            
        



        public static boolean isValid(long total) 
            if (total % 10 != 0) 
             else 
                        return true;
                
            return false;
        

        public static int sumOfEvenPlaces(long number) 
            int sum = 0;
            int remainder;
            while (number % 10 != 0 || number / 10 != 0) 
                remainder = (int) (number % 10);

                sum = sum + getDigit(remainder * 2);
                number /= 100;
            
            return sum;
        

        public static int getDigit(int number) 
            if (number > 9) 
                return (number % 10 + number / 10);
             
            return number;
        

        public static int sumOfOddPlaces(long number) 
            int sum = 0;
            int remainder;
            number /= 10;
            while (number % 10 != 0 || number / 10 != 0) 
                remainder = (int) (number % 10);
                sum = sum + getDigit(remainder * 2);
                number /= 100;
            
            return sum;
        
    

【问题讨论】:

编译器说错误在哪里?或者只是编译器说了什么?也请在您的问题中发布。 String CType;(String number) 【参考方案1】:

我使用枚举进行卡片类型检测:

package com.gabrielbauman.gist;

import java.util.regex.Pattern;

public enum CardType 

    UNKNOWN,
    VISA("^4[0-9]12(?:[0-9]3)0,2$"),
    MASTERCARD("^(?:5[1-5]|2(?!2([01]|20)|7(2[1-9]|3))[2-7])\\d14$"),
    AMERICAN_EXPRESS("^3[47][0-9]13$"),
    DINERS_CLUB("^3(?:0[0-5]\\d|095|6\\d0,2|[89]\\d2)\\d12,15$"),
    DISCOVER("^6(?:011|[45][0-9]2)[0-9]12$"),
    JCB("^(?:2131|1800|35\\d3)\\d11$"),
    CHINA_UNION_PAY("^62[0-9]14,17$");

    private Pattern pattern;

    CardType() 
        this.pattern = null;
    

    CardType(String pattern) 
        this.pattern = Pattern.compile(pattern);
    

    public static CardType detect(String cardNumber) 

        for (CardType cardType : CardType.values()) 
            if (null == cardType.pattern) continue;
            if (cardType.pattern.matcher(cardNumber).matches()) return cardType;
        

        return UNKNOWN;
    


然后你可以做CardType.detect("cardnumbergoeshere"),你会得到CardType.VISA等。

the gist 有一个单元测试结束。

为了验证,我有:

public boolean isValid(String cardNumber) 
    int sum = 0;
    boolean alternate = false;
    for (int i = cardNumber.length() - 1; i >= 0; i--) 
        int n = Integer.parseInt(cardNumber.substring(i, i + 1));
        if (alternate) 
            n *= 2;
            if (n > 9) 
                n = (n % 10) + 1;
            
        
        sum += n;
        alternate = !alternate;
    
    return (sum % 10 == 0);

应该可以的。

编辑:修正了 DINERS_CLUB 中的转义字符

【讨论】:

这对我帮助很大!我forked the gist 添加对中国银联卡的支持,也许您想将其编辑到您的答案中:-) 一些卡片范围已经增加。我更新了 Discover 和 VISA,因为它只是一个小改动。万事达卡现在也有 2221-2720,所以我使用 ^(?:5[1-5]|2(?!2([01]|20)|7(2[1-9]|3))[2-7])\\d14$ 和 Diner's Club ^3(?:0[0-5]\d|095|6\d0,2|[89]\d2)\d12,15$。不过答案很好! 我用你的范围更新了代码。谢谢@Gary 和@LionC!【参考方案2】:

这可能更符合您正在尝试做的事情:

    public static void main(final String args[])
    
        String cType = null;

        System.out.println("Enter a credit card number: ");
        final Scanner input = new Scanner(System.in);
        final String cardNumber = input.next();

        if (cardNumber.startsWith("4"))
        
            cType = "Visa";
        
        else if (cardNumber.startsWith("5"))
        
            cType =  "MasterCard";
        
        else if (cardNumber.startsWith("6"))
        
            cType =  "Discover";
        
        else if (cardNumber.startsWith("37"))
        
            cType =  "American Express";
        
        else
        
            cType =  "Unknown type";
        

        final long total = sumOfEvenPlaces(Long.valueOf(cardNumber)) + (sumOfOddPlaces(Long.valueOf(cardNumber)) * 2);

        if (isValid(total))
        
            System.out.println("The " + cType + " card number is valid");
        
        else
        
            System.out.println("The " + cType + " card number is invalid.");
        
    

在风格上,CType 应该以小写字母开头(例如cType)。您必须尝试使用​​ Scanner,而且我不确定我的实现是否能满足您的要求。

【讨论】:

这将是一个switch statement的好地方

以上是关于信用卡类型和验证的主要内容,如果未能解决你的问题,请参考以下文章

信用卡验证:卡名可以包含非 ASCII 字符吗?

使用 Abide 在 Zurb Foundation 上进行信用卡验证

ActiveMerchant 说有效卡的信用卡无效

使用信用卡和支付网关进行年龄验证

如何使用 jQuery 信用卡验证器

信用卡分析器和验证器