用 C 编写一个程序,将 Luhn 算法应用于信用卡验证

Write a program in C to apply Luhn's algorithm for credit card validation

我需要我的程序提示用户输入并在输入不符合信用卡格式(例如:负数或字母等)时重新提示,然后应用算法查看如果该号码是有效的信用卡号码,如果是,是 Visa、MasterCard 还是 AmEx。

我知道这个问题已经在这个网站上用不同的代码得到了回答,我发誓我阅读了所有我能找到的东西(在这个网站和网络上的其他地方)但是我真的很难理解C 语法,我想尝试自己想出一些东西,而不是复制我从其他答案中无法理解的代码。如果有人可以帮助我看看我到目前为止所做的事情并告诉我我做错了什么,我将非常感激。此外,非常感谢任何可以帮助我更好地理解 C 语法逻辑的提示。

我的程序正在编译,但是当我 运行 它以一种非常奇怪的方式运行时:当我输入一个输入时,有时它会说它无效(即使它是一个有效数字)有时在我按下 enter 后它不会 return 任何东西,并且无论我按下 return 键多少次都不会停止 运行ning。

到目前为止,这是我的代码:


#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void)
{
    printf("Please give me your credit card number:\n") ;

    long long card_num ;

    do
    {
        card_num = GetLongLong() ;
    }
    while (card_num < 1 || card_num > 9999999999999999) ;

    // Make a copy of the card number to be used and modified throughout the process.

    long long temp_num = card_num ;
    int digit = 0 ;
    int count = 0 ;
    int sum_a = 0 ;
    int sum_b = 0 ;

    // Isolate every digit from the credit card number using a loop and the variable 'digit'.
    // Keep track of the amount and position of each digit using variable 'count'.

    while (card_num >= 0)
    {
        digit = card_num % 10 ;
        count++ ;
        temp_num = (card_num - digit) / 10 ;
        break ;


     // Apply Luhn's algorithm using two different 'for' loops depending on the position of each digit.
        
        for (count = 0 ; count % 2 == 0 ; count++)
        {
            sum_a = sum_a + ((card_num % 10) * 2) ;
        
            while ((card_num % 10) * 2 >= 10)
            {
                sum_a = (sum_a % 10) + 1 ;
            } 
        }
        
        for (count = 0 ; count % 2 != 0 ; count++)
        {
            sum_b = sum_b + digit ;
        }
        
        return sum_a ;
        return sum_b ;
        return count ;
    }

    // Checking the validity of the number according to Luhn's algorithm

    int total_sum = sum_a + sum_b ;

    if (total_sum % 10 != 0)
    {
       printf("This is an invalid number.\n") ; 
    }

// If the number entered doesn't have the right amount of digits according
// to variable 'count', declare the number as invalid.

    if (count != 13 || count != 15 || count != 16)
    {
        printf("This is an invalid number.\n") ;
    }

// Reset value of variable 'temp_num' and apply calculations that will isolate the first two digits. 
// Store the results in a variable 'company_id'.

    temp_num = card_num ;
    int company_id ;

    while (temp_num > 100)
    {
        temp_num = card_num - (card_num % 10) ;
        company_id = temp_num / 10 ;
    }

    return company_id ;

// Print the type of credit card depending on the company ID and amount of digits.

    if (company_id > 50 && company_id < 56 && count == 16)
    {
        printf("MASTERCARD\n") ;
    }
    else if ((company_id == 4) && (count == 13 || count == 16))
    {
        printf("VISA\n") ;
    }
    else if ((company_id == 34 || company_id == 37) && (count == 15)) 
    {
        printf("AMEX\n") ;
    }
    else
    {
        printf("This is an invalid number.\n") ;
    }

    return 0 ;

}

你的答案乱七八糟,其中的部分与之前的答案不符合逻辑。

具体问题:

这个逻辑:

if (count != 13 || count != 15 || count != 16)

使每张卡片无效,s (||) 应该是 ands (&&) 才能工作。

这个循环没有意义:

while (card_num >= 0)
{
    digit = card_num % 10 ;
    count++ ;
    temp_num = (card_num - digit) / 10 ;
    break ;
    ...
}

break 是无条件的,因此它退出循环并忽略接下来的二十行。

您调用 return 五次时,您似乎拼接了其他地方的子程序,只有最后一次有效:

return sum_a ;
return sum_b ;
return count ;
return company_id ;
return 0 ;

在几个地方你使用 card_num 而你应该使用 temp_num.

一旦您知道卡无效,您将无法退出程序——而是继续测试。您未能确认卡片何时有效。

您计算卡号中的位数,但等到您 运行 进行其他检查后再测试该数字计数是否有效。

接下来是我对您的代码进行的修改,以解决上述问题和一些样式问题:

#include <stdio.h>
#include <cs50.h>
#include <math.h>

int main(void)
{
    printf("Please give me your credit card number: ") ;

    long long card_num = 0LL;

    while (card_num < 1LL || card_num > 9999999999999999LL)
    {
        card_num = GetLongLong();
    }

    // Make a copy of the card number to be used and modified throughout the process.

    long long temp_num = card_num;

    // Isolate every digit from the credit card number using a loop and the variable 'digit'.
    // Keep track of the amount and position of each digit using variable 'count'.

    int count = 0;

    while (temp_num > 0LL)
    {
        temp_num = temp_num / 10LL;
        count++;
    }

    // If the number entered doesn't have the right amount of digits according
    // to variable 'count', declare the number as invalid.

    if (count != 13 && count != 15 && count != 16)
    {
        printf("This is an invalid number (# of digits).\n");
        return 1;
    }

    // Reset value of variable 'temp_num' and apply calculations that will isolate the first two digits. 
    // Store the results in a variable 'company_id'.

    temp_num = card_num;

    while (temp_num > 100LL)
    {
        temp_num = temp_num / 10LL;
    }

    int company_id = temp_num;

    // Print the type of credit card depending on the company ID and amount of digits.

    if (company_id > 50 && company_id < 56 && count == 16)
    {
        printf("MASTERCARD\n") ;
    }
    else if ((company_id == 34 || company_id == 37) && (count == 15)) 
    {
        printf("AMEX\n") ;
    }
    else if ((company_id / 10 == 4) && (count == 13 || count == 16 || count == 19))
    {
        printf("VISA\n") ;
    }
    else
    {
        printf("This card was issued by an unknown company.\n");
    }

    // Apply Luhn's algorithm.

    int sum = 0;

    temp_num = card_num;

    for (int i = 1; i <= count; i++)
    {
        int digit = temp_num % 10LL;

        if (i % 2 == 0)
        {
            digit *= 2;

            if (digit > 9)
            {
                digit -= 9;
            }
        }

        sum += digit;

        temp_num /= 10LL;
    }

    // Checking the validity of the number according to Luhn's algorithm

    if (sum % 10 != 0)
    {
        printf("This is an invalid number (Luhn's algorithm).\n");
        return 1; 
    }

    printf("This is a valid number.\n");

    return 0;
} 

这不是一个完成的程序 -- 需要进行错误检查和其他详细信息。当双倍卡号大于 9 时,我没有对数字求和,而是使用减去 9 的更简单方法。

这里是我的解决方法,这个方法收到了var long的信用卡号,希望对你有帮助。

void check_card(long n)

{
    long temp_n = n;
    int count = 2;
    while(temp_n > 100)
    {
        temp_n = temp_n / 10;
        count ++;
    }

    long temp_n2 = n;
    int sum = 0;

    for (int i = 1; i <= count; i++)
    {
        int digit = temp_n2 % 10;
        if (i%2 == 0)
        {
            if (digit * 2 > 9)
            {
                sum += (digit * 2) - 9;
            }
            else
            {
                sum += digit * 2;
            }
        }
        else
        {
             sum += digit;
        }  
        temp_n2 /= 10;
    }

    bool flag = (sum % 10 == 0) ? true : false;

    if (count == 15 && (temp_n == 34 || temp_n == 37) && flag)
    {
        printf("AMEX\n");
    }
    else if(count == 16 && (temp_n > 50 && temp_n < 56) && flag)
    {
        printf("MASTERCARD\n");
    }
    else if((count == 13 || count == 16) && (temp_n / 10 ==4) && flag)
    {
        printf("VISA\n");
    }
    else
    {
        printf("INVALID\n");
    }