0

I've been stumped on Credit for a few weeks, I've learned a LOT in writing my code and I have fixed many errors. My code now passes all the checks except for these two errors and I cannot figure out why:

:( identifies 4111111111111113 as INVALID (invalid checksum)
    expected "INVALID\n", not "VISA\n"
:( identifies 4222222222223 as INVALID (invalid checksum)
    expected "INVALID\n", not "VISA\n"

From my understanding it should be returning as INVALID but my code is returning these as a valid VISA. Any help would be greatly appreciated. I think my Luhn's algorithm is failing these numbers but I am not sure why, here is my code:

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

// Function prototype
int countDigits(long card);

// Function definition
int countDigits(long card) {
    int count = 0;

    // Handle negative numbers
    if (card < 0) {
        card = -card;
    }

    // Count digits by repeatedly dividing by 10
    while (card != 0) {
        card /= 10;
        count++;
    }

    return count;
}

int main(void) {
    // Get credit card number from user
    long ccnum = get_long("Enter a credit card number: ");
    int numDigits = countDigits(ccnum);
    long temp = ccnum;
    int sum = 0;
    int sum2 = 0;
    int digit;
    int lastdigit;

    // Check if the input is between 13 and 16 digits long
    if (numDigits < 13 || numDigits > 16) {
        printf("INVALID\n");
        return 0;
    }

    // Extract the first two digits
    int firstTwoDigits = (int)(temp / pow(10, numDigits - 2));

    // Extract the first digit
    int firstDigit = (int)(temp / pow(10, numDigits - 1));

    // Check the card type
    if (numDigits == 15) {
        if (firstTwoDigits == 34 || firstTwoDigits == 37) {
            printf("AMEX\n");
            return 0;
        } else {
            printf("INVALID\n");
            return 0;
        }
    } else if (numDigits == 13) {
        if (firstDigit == 4) {
            printf("VISA\n");
            return 0;
        } else {
            printf("INVALID\n");
            return 0;
        }
    } else if (numDigits == 16) {
        if (firstDigit == 4) {
            printf("VISA\n");
            return 0;
        } else if (firstTwoDigits >= 51 && firstTwoDigits <= 55) {
            printf("MASTERCARD\n");
        } else {
            printf("INVALID\n");
            return 0;
        }
    }

    // Perform Luhn's algorithm validation
    for (int i = numDigits - 1; i >= 0; i--) {
        // Extract the current digit
        digit = (temp / ((long long)pow(10, i))) % 10;

        // If it's an odd position, multiply by 2
        if ((numDigits - i) % 2 == 1) {
            digit *= 2;
            // If the result is greater than 9, subtract 9
            if (digit > 9) {
                digit -= 9;
            }
            sum += digit;
        } else {
            // Add digits at even positions directly to sum2
            sum2 += digit;
        }
    }

    // Calculate total sum
    int totalSum = sum + sum2;

    // Check if the sum is divisible by 10
    bool passesLuhn = (totalSum % 10 == 0);

    if (!passesLuhn) {
        printf("INVALID\n");
        return 0;
    }

    return 0;
}

1 Answer 1

1

First, understand that whenever a return statement is executed, the code will immediately return to the calling code, or the operating system (if the return statement is in the main() code section. )

The posted code checks the length of the credit card number and the starting digit(s). If it finds a match, it identifies the cc number as valid, and immediately executes a return statement, terminating the program.

The code to check the checksum never executes for an otherwise valid number. The two check50 tests fail because the length and leading digits are correct, but the checksum is bad. These two tests are designed to catch this exact issue.

You need to rethink the logic of your program to assure that the length, starting digits AND the checksum are all valid before declaring that a cc number is valid. (Of course, any time any one check determines an invalid number, it's time to declare it invalid and terminate the program.)

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .