Can anyone help error check my Luhns algorithm code?

77 views Asked by At

I'm new to c, doing the cs50 course week 1.
Cannot seem to put my finger on dealing with 2 errors that check cs50 indicates.

I wrote this version of the credit card number checking code and it still gives me an error when I check it.
Apparently, it validates 4111111111111113 and 4222222222223 as visa numbers when they're not. (shows invalid checksum)

Here's my code:

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

int main(void)
{
    long long card_num = 0LL;
    do 
    {
        card_num = get_long_long("Number: ");
    }
    while (card_num < 1LL || card_num > 9999999999999999LL);

    int sum = 0;
    long long temp_num = card_num;
    int count = 0;

    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;
        count++; 
    }

    if (sum % 10 != 0)     
    {
        printf("INVALID\n");
        return 0;
    }
    else
    {
        long long temp_num = card_num;

        int count = 0;

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

        if (count != 13 && count != 15 && count != 16)
        {
            printf("INVALID\n");
            return 0;
        }

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

        int company_id = temp_num;
        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("INVALID\n");
        }

    }
}
1

There are 1 answers

0
NoDakker On

In testing out your code and adding in some temporary printf statements, it quickly became evident that the issue was that the Luhn check value "for" loop was not being executed because variable "count" was defined and initialized with a value of zero.

    int sum = 0;
    long long temp_num = card_num;
    int count = 0;                      /* Problem variable - set to zero */

    for (int i = 1; i <= count; i++)    /* Since count is zero, the for loop never executes */
    {
        int digit = temp_num % 10LL;
        if (i % 2 == 0) 
        {
            digit *= 2;

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

        temp_num /= 10LL;
        count++; 
    }

With that, the variable "sum" will contain a value of zero and the "if (sum % 10 != 0)" test will be false, which causes the program to continue on and falsely identify the entered test number as a valid "VISA" number.

With that, following is a refactored version of that block of code, utilizing string functionality.

#include <stdio.h>
#include <string.h>

int main(void)
{
    long long card_num = 0LL;
    char text[20];
    do
    {
        //card_num = get_long_long("Number: ");
        printf("Number: ");
        scanf("%lld", &card_num);
    }
    while (card_num < 1LL || card_num > 9999999999999999LL);

    int sum = 0;
    long long temp_num = card_num;
    sprintf(text, "%lld", card_num);

    for (int i = 1; i <= strlen(text); i++)
    {
        int digit = temp_num % 10LL;
        if (i % 2 == 0)
        {
            digit *= 2;

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

        printf("Digit: %d\n", digit);   /* Low tech debug method to monitor Luhn calculation    */
        sum += digit;
        temp_num /= 10LL;
    }

    printf("Sum: %d\n", sum);           /* Low tech debug method to monitor Luhn calculation    */

FYI, as noted, I substituted a "printf" prompt statement along with a "scanf" statement to input the credit card number since I do not have the CS50 library and functionality on my system; however, it is effectively getting the credit card number. With the refactored program following was a test utilizing one of your credit card examples.

craig@Vera:~/C_Programs/Console/CreditLuhn/bin/Release$ ./CreditLuhn
Number: 4111111111111113
Digit: 3
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 2
Digit: 1
Digit: 8
Sum: 32
INVALID

As noted, the final sum total is not divisible by "10" and so notes that the entered number is invalid.

There might need to be additional polish to the code, but the biggest things to take away are get familiar with debugging, even if it is as simple as temporarily inserting "printf" statements.