【发布时间】:2013-12-08 18:13:15
【问题描述】:
我是一名计算机科学入门课程的高中生。我们的任务如下:
信用卡号的最后一位是校验位,可防止抄录错误,例如一位数错误或两位数切换。以下方法用于验证实际的信用卡号码,但为简单起见,我们将使用 8 位数字而不是 16 位数字来描述它:
- 从最右边的数字开始,形成所有其他数字的总和。例如,如果信用卡号是 4358 9795,那么您的和就是 5+7+8+3 = 23。
- 将前面步骤中未包含的每个数字加倍。添加结果数字的所有数字。例如,对于上面给出的数字,将数字加倍,从倒数第二个开始,得到 18 18 10 8。将这些值中的所有数字相加得到 1+8+1+8+1+0+8 =27。
- 将前面两个步骤的总和相加。如果结果的最后一位为 0,则该数字有效。在我们的例子中,23 + 27 = 50,所以这个数字是有效的。
编写一个程序来实现这个算法。用户应提供一个 8 位数字,您应打印出该数字是否有效。 如果它无效,您应该打印出使数字有效的校验位的值。
除了粗体部分之外,我已经完成了所有工作。我的代码如下:
public class CreditCard
{
private String creditCardNumber;
private boolean valid;
private int checkDigit;
int totalSum;
/**
* Constructor for objects of class CreditCard
*/
public CreditCard(String pCreditCardNumber)
{
creditCardNumber = pCreditCardNumber;
checkDigit = Integer.parseInt(pCreditCardNumber.substring(creditCardNumber.length() - 1));
int sumOfDigits = checkDigit + Integer.parseInt(pCreditCardNumber.substring(6,7)) + Integer.parseInt(pCreditCardNumber.substring(3,4)) + Integer.parseInt(pCreditCardNumber.substring(1,2));
int dig7 = Integer.parseInt(pCreditCardNumber.substring(7,8));
int dig5 = Integer.parseInt(pCreditCardNumber.substring(5,6));
int dig3 = Integer.parseInt(pCreditCardNumber.substring(2,3));
int dig1 = Integer.parseInt(pCreditCardNumber.substring(0,1));
String string7 = Integer.toString(dig7);
int doubledDig7a = Integer.parseInt(string7.substring(0));
int doubledDig7b = 0;
if (dig7 * 2 >= 10)
{
doubledDig7a = Integer.parseInt(string7.substring(0));
doubledDig7b = 0;
}
String string5 = Integer.toString(dig5);
int doubledDig5a = Integer.parseInt(string7.substring(0));
int doubledDig5b = 0;
if (dig5 * 2 >= 10)
{
doubledDig5a = Integer.parseInt(string5.substring(0));
doubledDig5b = 0;
}
String string3 = Integer.toString(dig3);
int doubledDig3a = Integer.parseInt(string3.substring(0));
int doubledDig3b = 0;
if (dig3 * 2 >= 10)
{
doubledDig3a = Integer.parseInt(string3.substring(0));
doubledDig3b = 0;
}
String string1 = Integer.toString(dig1);
int doubledDig1a = Integer.parseInt(string1.substring(0));
int doubledDig1b = 0;
if (dig1 * 2 >= 10)
{
doubledDig1a = Integer.parseInt(string1.substring(0));
doubledDig1b = 0;
}
int doubleDigits = doubledDig1a + doubledDig1b + doubledDig3a + doubledDig3b + doubledDig5a + doubledDig5b + doubledDig7a + doubledDig7b;
totalSum = sumOfDigits + doubleDigits;
if (totalSum % 10 == 0)
{
valid = true;
}
else
{
valid = false;
}
}
public void makeItValid()
{
while (totalSum % 10 != 0)
{
checkDigit--;
if (totalSum % 10 == 0)
{
break;
}
}
}
public boolean isItValid()
{
return valid;
}
}
循环是我遇到的问题。每当它编译时,我总是会陷入无限循环。不过,看起来一切都应该正常工作。它应该减少校验位的值(不增加,所以我最终不会得到 10 或更高的校验位),然后将该数字加回总和,直到总和可被 10 整除,并且然后循环将结束。我使用的循环类型是否错误?任何意见,将不胜感激。
【问题讨论】:
-
只是一个评论:你的代码比你需要的多 100 倍
-
我知道这不适用于你的作业,但这里有一些你需要知道的。您从不输入任何银行号码或密码作为字符串。字符串被扔进一个池中,所以它们不会被垃圾收集器收集。如果你要在现实世界中这样做,黑客可以很容易地获取卡号。相反,您应该使用字符数组。您可以将所有字符重置为零,但您不能对字符串执行此操作,因为它们是不可变的。这只是一个提示。 TLDR: 切勿将字符串用于敏感数字。
-
@Mr.Polywhirl : 1. 并不是所有的字符串都会被自动保留,在这种情况下信用卡号不会是 - 请参阅
String.intern()文档。 2. 如果黑客可以“非常轻松”地访问您的虚拟机内存,那么您还有其他问题。
标签: java loops if-statement