Java 信用卡类型和验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20377978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Credit card type and validation
提问by user2947240
I would like to run a program that can determine the validation and type of credit card number based of number entered. Compiler shows notification that there is an error in my coding but I cannot detect where is it. The program is also cannot be run. Below is the coding,
我想运行一个程序,该程序可以根据输入的数字确定信用卡号的验证和类型。编译器显示我的编码有错误的通知,但我无法检测到它在哪里。该程序也无法运行。下面是编码,
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;
}
}
回答by eebbesen
This may be more along the lines of what you're trying to do:
这可能更符合您要执行的操作:
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.");
}
}
On a stylistic note, CType
should start with a lower case letter (e.g. cType
). You'll have to experiment with the use of Scanner
as well as I'm not sure my implementation will do what you're looking for.
在文体上,CType
应该以小写字母开头(例如cType
)。您必须尝试使用Scanner
以及我不确定我的实现是否会满足您的要求。
回答by Gabriel Bauman
I do card type detection with an enum:
我使用枚举进行卡片类型检测:
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])\d{14}$"),
AMERICAN_EXPRESS("^3[47][0-9]{13}$"),
DINERS_CLUB("^3(?:0[0-5]\d|095|6\d{0,2}|[89]\d{2})\d{12,15}$"),
DISCOVER("^6(?:011|[45][0-9]{2})[0-9]{12}$"),
JCB("^(?:2131|1800|35\d{3})\d{11}$"),
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;
}
}
You can then do CardType.detect("cardnumbergoeshere")
and you'll get back CardType.VISA, etc.
然后你可以这样做CardType.detect("cardnumbergoeshere")
,你会得到 CardType.VISA 等。
There's a unit test over at the gist.
有一个单元测试在gist。
For validation, I have:
为了验证,我有:
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);
}
That should do it.
那应该这样做。
Edit: fixed escape characters in DINERS_CLUB
编辑:修复 DINERS_CLUB 中的转义字符