luhn的异常行为在c中的算法

发布于 2025-02-13 03:15:22 字数 3896 浏览 0 评论 0原文

我一直在进行CS50课程,并偶然发现了这个“信用”问题。目前,我正在测试它,并且由于工作表中提供的案例不足,我去了推荐的PayPal测试卡号: https://developer.paypal.com/api/nvp-soap/payflow/integration-guide/test-transactions/#standard-test-test-cards-cards Particularly:

  • Mastercard 5555555555554444
  • Mastercard 5105105105105100
  • Mastercard 5199999999999991
  • Mastercard 5299999999999990

These refuse to cooperate.我的程序计算了卢恩为他们的价值,并且它不接近10的乘数;我是否缺少一些东西,因为其他提供商的工作状况非常好。

代码检查的结果:

:( identifies 5555555555554444 as MASTERCARD
    expected "MASTERCARD\n", not "114\nINVALID\n..."
:( identifies 5105105105105100 as MASTERCARD
    expected "MASTERCARD\n", not "47\nINVALID\n"

我的代码:

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

int get_sum_from_second_to_last(long temp_number);

int get_sum_from_odd_digits(long temp_number);

int length(long temp_number);

int return_first_n_digits(int n, long temp_number, int length);

int main()
{
    int final_sum = 0;
    long number = 0;
    do
    {
        number = get_long("Number: ");
    }
    while(number<0);
    final_sum = get_sum_from_second_to_last(number) + get_sum_from_odd_digits(number);
    printf("%i\n", final_sum);
    if(final_sum % 10 == 0)
    {
        if(length(number) == 15 && (return_first_n_digits(2, number, length(number)) == 34 || return_first_n_digits(2, number, length(number)) == 37))
        {
            printf("AMEX\n");
        }
        else
        {
            if((length(number) == 16 || length(number) == 13) && return_first_n_digits(1, number, length(number)) == 4)
            {
                printf("VISA\n");
            }
            else
            {
                if(length(number) == 16 && (return_first_n_digits(2, number, length(number)) == 51 || return_first_n_digits(2, number, length(number)) == 52 || return_first_n_digits(2, number, length(number)) == 53 || return_first_n_digits(2, number, length(number)) == 54 || return_first_n_digits(2, number, length(number)) == 55))
                {
                    printf("MASTERCARD\n");
                }
                else
                {
                    printf("This card provider recognition is not supported\n");
                }
            }
        }
    }
    else
    {
        printf("INVALID\n");
    }
}

int get_sum_from_second_to_last(long temp_number)
{
    int digit_current = 0;
    int counter = 1;
    int sum = 0;
    do
    {
        digit_current = temp_number % 10;
        if(counter%2 == 0)
        {
            if((digit_current*2)%10!=0)
            {
                sum = sum + (digit_current*2)%10 + (digit_current*2)/10;
            }
            else
            {
                sum = sum + digit_current*2;
            }
        }
        temp_number = temp_number/10;
        counter += 1;
    }
    while(temp_number);
    return sum;
}

int get_sum_from_odd_digits(long temp_number)
{
    int digit_current = 0;
    int counter = 1;
    int sum = 0;
    do
    {
        digit_current = temp_number % 10;
        if(counter%2 != 0)
        {
            sum = sum + digit_current;
        }
        temp_number = temp_number/10;
        counter += 1;
    }
    while(temp_number);
    return sum;
}

int length(long temp_number)
{
    int counter = 0;
    do
    {
        temp_number = temp_number/10;
        counter++;
    }
    while(temp_number);
    return counter;
}

int return_first_n_digits(int n, long temp_number, int length)
{
    int i;
    for(i = 0; i < length - n; i++)
    {
        temp_number = temp_number/10;
    }
    return temp_number;
}

I've been doing a CS50 course and stumbled upon this "Credit" problem. At the moment I'm testing it and due to insufficient cases provided in worksheet, I went to the recommended PayPal testing card numbers: https://developer.paypal.com/api/nvp-soap/payflow/integration-guide/test-transactions/#standard-test-cards
Particularly:

  • Mastercard 5555555555554444
  • Mastercard 5105105105105100
  • Mastercard 5199999999999991
  • Mastercard 5299999999999990

These refuse to cooperate. My program calculates the Luhn's value for them, and it's not close to being a multiplier of 10; am I missing something, because other providers are working perfectly fine.

Results from code check:

:( identifies 5555555555554444 as MASTERCARD
    expected "MASTERCARD\n", not "114\nINVALID\n..."
:( identifies 5105105105105100 as MASTERCARD
    expected "MASTERCARD\n", not "47\nINVALID\n"

My code:

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

int get_sum_from_second_to_last(long temp_number);

int get_sum_from_odd_digits(long temp_number);

int length(long temp_number);

int return_first_n_digits(int n, long temp_number, int length);

int main()
{
    int final_sum = 0;
    long number = 0;
    do
    {
        number = get_long("Number: ");
    }
    while(number<0);
    final_sum = get_sum_from_second_to_last(number) + get_sum_from_odd_digits(number);
    printf("%i\n", final_sum);
    if(final_sum % 10 == 0)
    {
        if(length(number) == 15 && (return_first_n_digits(2, number, length(number)) == 34 || return_first_n_digits(2, number, length(number)) == 37))
        {
            printf("AMEX\n");
        }
        else
        {
            if((length(number) == 16 || length(number) == 13) && return_first_n_digits(1, number, length(number)) == 4)
            {
                printf("VISA\n");
            }
            else
            {
                if(length(number) == 16 && (return_first_n_digits(2, number, length(number)) == 51 || return_first_n_digits(2, number, length(number)) == 52 || return_first_n_digits(2, number, length(number)) == 53 || return_first_n_digits(2, number, length(number)) == 54 || return_first_n_digits(2, number, length(number)) == 55))
                {
                    printf("MASTERCARD\n");
                }
                else
                {
                    printf("This card provider recognition is not supported\n");
                }
            }
        }
    }
    else
    {
        printf("INVALID\n");
    }
}

int get_sum_from_second_to_last(long temp_number)
{
    int digit_current = 0;
    int counter = 1;
    int sum = 0;
    do
    {
        digit_current = temp_number % 10;
        if(counter%2 == 0)
        {
            if((digit_current*2)%10!=0)
            {
                sum = sum + (digit_current*2)%10 + (digit_current*2)/10;
            }
            else
            {
                sum = sum + digit_current*2;
            }
        }
        temp_number = temp_number/10;
        counter += 1;
    }
    while(temp_number);
    return sum;
}

int get_sum_from_odd_digits(long temp_number)
{
    int digit_current = 0;
    int counter = 1;
    int sum = 0;
    do
    {
        digit_current = temp_number % 10;
        if(counter%2 != 0)
        {
            sum = sum + digit_current;
        }
        temp_number = temp_number/10;
        counter += 1;
    }
    while(temp_number);
    return sum;
}

int length(long temp_number)
{
    int counter = 0;
    do
    {
        temp_number = temp_number/10;
        counter++;
    }
    while(temp_number);
    return counter;
}

int return_first_n_digits(int n, long temp_number, int length)
{
    int i;
    for(i = 0; i < length - n; i++)
    {
        temp_number = temp_number/10;
    }
    return temp_number;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小鸟爱天空丶 2025-02-20 03:15:22

该问题似乎在您的功能中,以概括int get_sum_from_second_to_last函数中的偶数数字。在该功能中,数字乘以两个因子。然后,根据有关Luhn算法应该如何工作的信息,如果结果为两个数字,则应该将这些数字添加在一起以得出一个数字。看来该功能中的当前测试并不总是发生。由于将一个数字乘以“ 2”的值只能导致“ 10”到“ 18”的两个数字数字,因此可以通过仅从计算出的结果中减去“ 9”的值有效地得出数字的求和。 。

因此,我提供以下代码段作为偶数数字的替代总结。

int get_sum_from_second_to_last(long temp_number)
{
    int digit_current = 0;
    int counter = 1;
    int sum = 0;
    do
    {
        digit_current = temp_number % 10;
        if(counter%2 == 0)
        {
            if((digit_current*2) > 9)
            {
                sum = sum + (digit_current * 2 - 9);
            }
            else
            {
                sum = sum + digit_current * 2;
            }
        }
        temp_number = temp_number/10;
        counter += 1;
    }
    while(temp_number);

    printf("Even digit sum: %d\n", sum);

    return sum;
}

仅供参考,您可以省略printf()调用。我补充说,只是为了进行视觉澄清。

通过这种更改,我测试了您叙述中的四个样本编号,它们都产生了有效的万事达卡结果。

Number: 5299999999999990
Even digit sum: 64
Current digit: 0
Current digit: 9
Current digit: 9
Current digit: 9
Current digit: 9
Current digit: 9
Current digit: 9
Current digit: 2
Odd digit sum: 56
Final sum: 120
MASTERCARD

作为进一步的测试,我实际上测试了AMEX和Visa的数字,并且签证也有效。

我希望这阐明了事情。

问候。

The issue appears to be in your function for summing up the even numbered digits in the int get_sum_from_second_to_last function. In that function, the digits are multiplied by a factor of two. Then according to information on how the Luhn's algorithm is supposed to work, if the result is a two-digit number, those digits are then supposed to be added together to derive a single digit. It appears that doesn't always happen with the current testing within that function. Since the value of multiplying one digit by "2" can only result in two-digit numbers from "10" to "18", one can effectively derive the summation of the digits by just subtracting the value of "9" from the calculated result.

With that, I offer up the following code snippet as an alternative summation of the even-numbered digits.

int get_sum_from_second_to_last(long temp_number)
{
    int digit_current = 0;
    int counter = 1;
    int sum = 0;
    do
    {
        digit_current = temp_number % 10;
        if(counter%2 == 0)
        {
            if((digit_current*2) > 9)
            {
                sum = sum + (digit_current * 2 - 9);
            }
            else
            {
                sum = sum + digit_current * 2;
            }
        }
        temp_number = temp_number/10;
        counter += 1;
    }
    while(temp_number);

    printf("Even digit sum: %d\n", sum);

    return sum;
}

FYI, you can leave out the printf() call. I added that just for some visual clarification.

With that change, I tested out the four sample numbers in your narrative and they all produced a valid MASTERCARD result.

Number: 5299999999999990
Even digit sum: 64
Current digit: 0
Current digit: 9
Current digit: 9
Current digit: 9
Current digit: 9
Current digit: 9
Current digit: 9
Current digit: 2
Odd digit sum: 56
Final sum: 120
MASTERCARD

As a further test, I actually tested out a number for AMEX and for VISA and those worked as well.

I hope that clarifies things.

Regards.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文