Luhn 检查信用卡是否有效的算法

问题描述 投票:0回答:1

我已经用 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;
    }
}
c cs50
1个回答
1
投票

可能出现的问题:

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)
并仅使用整数数学。

建议不要在任何地方使用浮点数学来解决这个整数问题。

© www.soinside.com 2019 - 2024. All rights reserved.