Home > database >  CS50 Credit: Luhn's Algorithm - Please assist
CS50 Credit: Luhn's Algorithm - Please assist

Time:02-03

I'm a beginner in CS50 trying to do the Credit problem from Problem Set 1. We are using C. The problem asks us to validate credit card numbers using Luhn's algorithm. I was going to use an array, but code using one wasn't easy to understand for me.

I'm trying to type out the full luhn's formula to calculate. I don't know where I'm messing up. Every time I run a card number that's supposed to be valid, it's never card_total % 10 = 0 like it should be.

Example Card Number: 4003600000000014 => checksum total (int card_total) = 33

Below is just code that asks for the credit card number, runs it through the algorithm, and prints out the total checksum just for me to see if it's working properly. I know this is really long, but this is just for my understanding of all the pieces. I've written much shorter and nicer code before. I swear!

TIA!

EDIT: I run my code in the cs50 VS virtual codespace, which uses Linux I think. I will take the advice of changing the other ints to longs and see if this fixes my problem. My formulas are consistent, so this is a formatting issue. Once this is fixed, the rest of the problem is easy to solve.

Someone mentioned my complicated calculations. Sorry. I know this could be more brief, but I just wanted to follow the algorithm so I can see what's going on. The lecture for this week didn't touch on going through arrays or manipulating strings, so I'm just doing what I know so far in C. This would be a lot easier in python.

EDIT 2: All that needed to change was int to long. The code now works perfectly and incorporates properly with the rest of my code checking for Amex, Visa, etc. THANK YOU SO MUCH!

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

int get_number(void);

int main(void)
{
    long n = get_number();

//calculating card number with modulo

    long a = ((n % 10000000000000000) / 1000000000000000);
    long b = ((n % 1000000000000000) / 100000000000000);
    long c = ((n % 100000000000000) / 10000000000000);
    long d = ((n % 10000000000000) / 1000000000000);
    long e = ((n % 1000000000000) / 100000000000);
    long f = ((n % 100000000000) / 10000000000);
    long g = ((n % 10000000000) / 1000000000);
    long h = ((n % 1000000000) / 100000000);
    long i = ((n % 100000000) / 10000000);
    long j = ((n % 10000000) / 1000000);
    long k = ((n % 1000000) / 100000);
    long l = ((n % 100000) / 10000);
    long m = ((n % 10000) / 1000);
    long ene = ((n % 1000) / 100);
    long o = ((n % 100) / 10);
    long p = ((n % 10) / 1);                              //The "/ 1" is just for visualization

    // multiply odd numbers by 2                          //Also for visualization
    long q = a * 2;
    long r = c * 2;
    long s = e * 2;
    long t = g * 2;
    long u = i * 2;
    long v = k * 2;
    long w = m * 2;
    long x = o * 2;

    //process odd products                   //Luhn's has exceptions for double digit numbers

    long qq;
    if (q < 10)
    {
            qq = ((q % 10)   ((q % 100)/10));
    }
    else if (q > 10)
        {
            qq = (q % 10)   1;
        }
    else if (q == 10)
        {
            qq = 1;
        }
        else
        {
            qq = q;
        }

    long rr;
    if (r < 10)
        {
             rr = ((r % 10)   ((r % 100) / 10));
        }
        else if (r > 10)
            {
                rr = (r % 10)   1;
            }
        else if (r == 10)
            {
                rr = 1;
            }
        else
            {
                rr = r;
            }

    long ss;
    if (s < 10)
        {
             ss = ((s % 10)   ((s % 100) / 10));
        }
        else if (s > 10)
            {
                ss = (s % 10)   1;
            }
        else if (s == 10)
            {
                ss = 1;
            }
        else
            {
                ss = s;
            }

    long tt;
     if (t < 10)
        {
            tt = ((t % 10)   ((t % 100) / 10));
        }
        else if (t > 10)
            {
                tt = (t % 10)   1;
            }
        else if (t == 10)
            {
                tt = 1;
            }
        else
            {
                tt = t;
            }

    long uu;
     if (u < 10)
        {
             uu = ((u % 10)   ((u % 100) / 10));
        }
        else if (u > 10)
            {
                uu = (u % 10)   1;
            }
        else if (u == 10)
            {
                uu = 1;
            }
        else
            {
                uu = u;
            }

    long vv;
     if (v < 10)
        {
             vv = ((v % 10)   ((v % 100) / 10));
        }
        else if (v > 10)
            {
                vv = (v % 10)   1;
            }
        else if (v == 10)
            {
                vv = 1;
            }
        else
            {
                vv = v;
            }

    long ww;
     if (w < 10)
        {
                ww = ((w % 10)   ((w % 100) / 10));
        }
        else if (w > 10)
            {
                ww = (w % 10)   1;
            }
        else if (w == 10)
            {
                ww = 1;
            }
        else
            {
                ww = w;
            }

    long xx;
     if (x < 10)
        {
                xx = ((x % 10)   ((x % 100) / 10));;
        }
        else if (x > 10)
            {
                xx = (x % 10)   1;
            }
        else if (x == 10)
            {
                xx = 1;
            }
        else
            {
                xx = x;
            }

    //Sum processed odd products
    long total_odd = qq   rr   ss   tt   uu   vv   ww   xx;

    //sum total odd products and even card numbers
    long bb = ((b % 10)   ((b % 100) / 10));
    long dd = ((d % 10)   ((d % 100) / 10));
    long ff = ((f % 10)   ((f % 100) / 10));
    long hh = ((h % 10)   ((h % 100) / 10));
    long jj = ((j % 10)   ((j % 100) / 10));
    long ll = ((l % 10)   ((l % 100) / 10));
    long eneene = ((ene % 10)   ((ene % 100) / 10));
    long pp = ((p )   ((p % 100) / 10));

    long total_even = bb   dd   ff   hh  jj   ll   eneene   pp;

    //sum odd & even
    long card_total = total_odd   total_even;

    printf(" %li\n", card_total);
}

int get_number(void)                                         //Works perfectly
{   long n;
    do
    {
        n = get_long("Number: ");                            // Records credit card number
    }
    while (n < 1000000000000 || n > 5599999999999999); // CC at least 13 digits but < 17 digits
    return n;
}

CodePudding user response:

Trying out your code and debugging it, the issue I found right away is that the return size element for your "get_number" function is too small.

int get_number(void);

When I debugged the returned value to the main function, the value was a negative number since the integer return value is too small for your long integer.

Changing the function definition to "long get_number(void)" in the prototype and the function, allowed for the entered value to flow back to the main function and get tested properly. Following was the test output on my terminal (FYI, I added a couple of printf statements to illustrate that the entered value was flowing through properly).

@Vera:~/C_Programs/Console/CC_Luhn/bin/Release$ ./CC_Luhn 
Number: 4003600000000014
Value stored is: 4003600000000014
Returned number: 4003600000000014
 20

Just as a double-check, I ran a Luhn calculator program I had built some time back to answer a similar problem. Following is the output again using your credit card example as input.

@Vera:~/C_Programs/Console/Luhn/bin/Release$ ./Luhn 
Enter a number: 4003600000000014
Length of number is: 16
Digit is: 4 Value is: 8 Sum is 8
Digit is: 0 Value is: 0 Sum is 8
Digit is: 0 Value is: 0 Sum is 8
Digit is: 3 Value is: 3 Sum is 11
Digit is: 6 Value is: 3 Sum is 14
Digit is: 0 Value is: 0 Sum is 14
Digit is: 0 Value is: 0 Sum is 14
Digit is: 0 Value is: 0 Sum is 14
Digit is: 0 Value is: 0 Sum is 14
Digit is: 0 Value is: 0 Sum is 14
Digit is: 0 Value is: 0 Sum is 14
Digit is: 0 Value is: 0 Sum is 14
Digit is: 0 Value is: 0 Sum is 14
Digit is: 0 Value is: 0 Sum is 14
Digit is: 1 Value is: 2 Sum is 16
Digit is: 4 Value is: 4 Sum is 20
Valid

The result of the final calculation was the value of "20" which is a number that ends in zero, which indicates a valid number.

This might have been a bit verbose, but the bottom line is be careful mixing your integer sizes in functions and formulas.

Give that a try to see if it meets the spirit of your project.

  • Related