我已经用 C 语言编写了 Luhn 算法的脚本。我得到了正确的卡类型检查结果。与美国运通卡一样,万事达卡和维萨卡的功能都是正确的。但我没有得到卢恩算法的结果。具体针对以下代码中的check_sum函数。这里可能有什么问题?
#include <cs50.h>
#include <math.h>
#include <stdio.h>
long get_card_no(void);
int digit_count(long card_no);
int check_amex(long card_no, int noDigits);
int check_mastercard(long card_no, int noDigits);
int check_visa(long card_no, int noDigits);
int check_sum(long card_no, int noDigits);
int main(void)
{
long card_no = get_card_no();
int noDigits = digit_count(card_no);
int amex = check_amex(card_no, noDigits);
int mastercard = check_mastercard(card_no, noDigits);
int visa = check_visa(card_no, noDigits);
int checkSum = check_sum(card_no, noDigits);
if (checkSum == 0)
{
if (amex)
{
printf("AMEX\n");
}
else if (mastercard)
{
printf("MASTERCARD\n");
}
else if (visa)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
else
{
printf("INVALID\n");
}
}
long get_card_no(void)
{
long n;
do
{
n = get_long("Number: ");
}
while(n < 0);
return n;
}
int digit_count(long card_no)
{
int count = 0;
while(card_no > 1)
{
card_no = card_no / 10;
count++;
}
return count;
}
int check_sum(long card_no, int noDigits)
{
int digit1;
int digit2;
int sum1 = 0;
int sum2 = 0;
int sum;
for (int i = 1; i < noDigits; i += 2)
{
digit1 = (int)(card_no / pow(10, i)) % 10;
digit1 *= 2;
if (digit1 > 9)
{
digit1 = digit1 / 10 + digit1 % 10;
}
sum1 += digit1;
}
for (int j = 0; j < noDigits; j += 2)
{
digit2 = (int)(card_no / pow(10, j)) % 10;
sum2 += digit2;
}
sum = sum1 + sum2;
return sum % 10;
}
int check_amex(long card_no, int noDigits)
{
int first_digit = card_no / pow(10, (noDigits - 1));
int second_digit = (int)(card_no / pow(10, (noDigits - 2))) % 10;
if (noDigits == 15 && first_digit == 3 && (second_digit == 4 || second_digit == 7))
{
return 1;
}
else
{
return 0;
}
}
int check_mastercard(long card_no, int noDigits)
{
int first_digit = card_no / pow(10, (noDigits - 1));
int second_digit = (int)(card_no / pow(10, (noDigits - 2))) % 10;
if (noDigits == 16 && first_digit == 5 && (second_digit == 1 || second_digit == 2 || second_digit == 3 || second_digit == 4 || second_digit == 5))
{
return 1;
}
else
{
return 0;
}
}
int check_visa(long card_no, int noDigits)
{
int first_digit = card_no / pow(10, (noDigits - 1));
if ((noDigits == 16 || noDigits == 13) && first_digit == 4)
{
return 1;
}
else
{
return 0;
}
}
可能出现的问题:
32 位
long
当 long get_card_no(void)
为 32 位时,
long
可能无法准确处理 16 位信用卡号。使用 long long
至少 64 位。
数字计数
当然
while(card_no > 1)
应该是while(card_no > 0)
。
使用整数数学
当double pow(10, x)
数字时,
x >= 16
会遇到麻烦(不精确的 10 次方计算)。相反,形成一个 long long pow10ll(x)
并仅使用整数数学。
建议不要在任何地方使用浮点数学来解决这个整数问题。