题目描述:
信用卡号遵循下面的模式。一个信用卡号必须是13 到 16 位的整数。它的开头必须是:
- 4,指 Visa 卡
- 5,指 Master 卡
- 37,指 American Express 卡
- 6,指 Discover 卡
在 1954 年,IBM 的 Hans Luhn 提出一种算法,该算法可以验证信用卡号的有效性。这个算法在确定输入的卡号是否正确,或者这张信用卡是否被扫描仪正确扫描方面是非常有用的。遵循这个合法性检测可以生成所有的信用卡号,通常称之为 Luhn 检测或者 Mod10 检测,可以如下描述(为了方便解释,假设卡号为 4388576018402626):
1)从左到右对偶数位数字翻倍。如果对某个数字翻倍之后的结果是一个两位数,那么就将这两位加在一起得到一位数。
2)现在将第一步得到的所有一位数相加。
4 + 4 + 8 + 2 + 3 + 1 + 7 + 8 = 37
3)将卡号里从右到左在奇数位上的所有数字相加。
6 + 6 + 0 + 8 + 0 +7 + 8 + 3 = 38
4)将第二步和第三步得到的结果相加。
37 + 38 = 75
5)如果第四步得到的结果能被 10 整除,那么卡号是合法的;否则,卡号是不合法的。例如,号码 4388576018402626 是不合法的,但是号码 4388576018410707 是合法的。编写程序,提示用户输入一个 long 型整数的信用卡号码,显示这个数字是合法的还是非法的。使用下面的方法设计程序:
下面是程序的运行示例:(你也可以通过将输入作为一个字符串输入,以及对字符串进行处理来验证信用卡卡号。)
代码:
import java.util.Scanner;
public class Test12 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter a credit card number as a long interger:");
long number = in.nextLong();
if(isValid(number))
System.out.println(number + " is valid");
else
System.out.println(number + " is invalid");
in.close();
}
/** Return true if the card number is valid */
public static boolean isValid(long number) {
if(13 <= getSize(number) && getSize(number) <= 16)
if(prefixMatched(number,4)||prefixMatched(number,5)||prefixMatched(number,37)||prefixMatched(number,6))
if((sumOfDoublieEvenPlace(number) + sumOfOddplace(number)) % 10 == 0)
return true;
return false;
}
/** Get the result from Step 2 */
public static int sumOfDoublieEvenPlace(long number) {
String numberString = String.valueOf(number);
int sum = 0;
for(int i = 0; i < getSize(number); i += 2)
{
sum += getDigit(2 * Integer.parseInt(String.valueOf(numberString.charAt(i))));
}
return sum;
}
/** Return this number if it is a single digit, otherwise,
* return the sum of the two digits */
public static int getDigit(int number) {
if(number < 10)
return number;
return number % 10 + number / 10;
}
/** Return sum of odd-place digits in number */
public static int sumOfOddplace(long number) {
int sum = 0;
while(true)
{
if(number == 0)
break;
sum += number % 10;
number /= 100;
}
return sum;
}
/** Return true if the digit d is a prefix for number
* 如果数字d是number的前缀就返回true
*/
public static boolean prefixMatched(long number,int d) {
if(d == getPrefix(number,getSize(d)))
return true;
return false;
}
/** Return the number of digits in d */
public static int getSize(long d) {
return String.valueOf(d).length();
}
/** Return the first k number of digits from number. If the
* number of digits in number is less than k, return number.
* 返回number的前k位数。如果number的位数少于k,返回number。
*/
public static long getPrefix(long number,int k) {
if(getSize(number) < k)
return number;
long prefix = number;
for(int i = 0; i < getSize(number) - k; i++)
{
prefix /= 10;
}
return prefix;
}
}
运行结果:
结果一:
Enter a credit card number as a long interger:
4388576018410707
4388576018410707 is valid
结果二:
Enter a credit card number as a long interger:
4388576018402626
4388576018402626 is invalid