My attempt at Luhn's algorithm (for credit card validity) seems to recognise some cards but not others

246 Views Asked by At

I've constructed some code to simulate Luhn's algorithm for checking the validity of credit cards. It successfully recognises American Express cards (15 digit numbers beginning in 34 or 37), but when I try Mastercard (16 digits, beginning with 51, 52, 53, 54, or 55), it doesn't recognise them. Visa cards have 13 or 16 digits and start with the digit 4, my code seems to correctly identity the 16 digit cases but not the 13 digit ones. I've gone through my code and double checked my numerical ranges and I can't seem to diagnose exactly why some cards go through but others don't. Any help would be greatly appreciated.

Edit:

I've almost fixed the problem, I've modified it, and now all the card numbers check out, but now it's recognising an invalid number (4111111111111113) as Visa. Here's my updated code:

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

long long number;

int main(void)
{
    long long i = 0;
    long long b;
    long long m = 10;
    long long n = 1;

    number = get_long_long("Number?\n");

    do
    {
        long long a = number % m;
        b = number - a;
        long long c = b % (m * 10);
        long long d = c / m;
        long long e = d * 2;
        if (e < 9)
        {
            i = i + e;
        }
        else
        {
            i = i + (e - 10 + 1);
        }
        
        {
            m = m * 100;
        }
    }
    while (b > 0);

    do
    {
        long long a = number % n;
        b = number - a;
        long long c = b % (n * 10);
        long long d = c / n;
        long long e = d;
        if (e < 9)
        {
            i = i + e;
        }
        else
        {
            i = i + (e - 10 + 1);
        }
        
        {
            n = n * 100;
        }
    }
    while (b > 0);

    int f = i % 10;
    if (((f == 0) && (number > 339999999999999) && (number < 350000000000000)) || ((number > 369999999999999) && (number < 380000000000000)))
    {
        printf("AMEX\n");
    }
    else
    if ((f == 0) && (number > 5099999999999999) && (number < 5600000000000000))
    {
        printf("MASTERCARD\n");
    }
    else
    if (((f == 0) && ((number > 3999999999999) && (number < 5000000000000))) || ((number > 3999999999999999) && (number < 5000000000000000)))
    {
        printf("VISA\n");
    }
    else
    {
        printf("INVALID\n");
    }
}
1

There are 1 best solutions below

4
On

I see that you are having trouble trying to verify the length of some cards. To fix this use a function that automatically checks the length of a long. You can use some logic with the function to properly identify the Visa lengths.

Here is the function to check the length of a long variable.

int get_long_len(long value)
{
    int l = 1;
    while (value > 9)
    {
        l++;
        value /= 10;
    }
    return l;
}

It takes in the long value and returns the length.