ccs50luhn

Credit card validation check in C programming


This a problem from CS50 finding validation of credit card number using luhn's algorithm. I wrote this code but whenever I put any credit card number, the output comes as invalid.Can anyone please help me what my mistake here and how can I move forward with this code.

This is luhn's algorithm formula-- most cards use an algorithm invented by Hans Peter Luhn of IBM. According to Luhn’s algorithm, you can determine if a credit card number is (syntactically) valid as follows:

Multiply every other digit by 2, starting with the number’s second-to-last digit, and then add those products’ digits together. Add the sum to the sum of the digits that weren’t multiplied by 2. If the total’s last digit is 0 (or, put more formally, if the total modulo 10 is congruent to 0), the number is valid!

//Project Using Luhn's Algorithm - Credit Card validation

#include<cs50.h>
#include<stdio.h>
#include<string.h>
int main()
{
   long long ccnum = 0;



    int digitcounter = 0 ;
    char result[11] ;
    int sum = 0 ;
    int  divisor = 10 ;

    do
    {
      ccnum = get_long("Enter your credit card number: ") ;
    }
    while (ccnum <= 0) ;

//--------------------CHECKSUM--------------------------------

    //Case-01(Multiply every other digit by 2):

    long long tempccnum = ccnum ;
    while (tempccnum > 0)
    {
        int lastdigit = tempccnum % 10 ;
        sum = sum + lastdigit ;
        tempccnum = tempccnum / 100 ;
    }

    // Case-02(Multiplication every other digit by 2):

    tempccnum = ccnum / 10 ;
    while(tempccnum > 0)
    {
        int secondlastdigit = (tempccnum % 10) ;

        int tempmultiply = secondlastdigit*2 ;

        sum = sum + (tempmultiply % 10) + (tempmultiply / 10)  ;

        tempccnum = tempccnum / 100 ;
    }
//----------first two digit extraction------------

   long long initdigit = 0, tempinitdigit = 0 ;

   while(ccnum)
   {
     initdigit = tempinitdigit  ; // initdigit will hold the first two digits.
     tempinitdigit = ccnum  ;
     ccnum = ccnum/10 ;
   }




//-------------Digit counter----------
    while(ccnum != 0)
    {
          // iterate until ccnum becomes 0
         // remove last digit from ccnum in each iteration
        // increase digitcounter by 1 in each iteration

        ccnum = ccnum / 10 ;
        digitcounter++ ;
    }
  //------------------Final part - Condition checking------------------------

    if(sum % 10 == 0)
    {
        if (digitcounter == 15 && (initdigit == 34 || initdigit == 37))
        {
            strcpy(result, "AMEX\n") ;
        }

        else if (digitcounter == 16 && (initdigit >= 51 && initdigit <=55))
        {
             strcpy(result,"MASTERCARD\n") ;
        }

        else if ((digitcounter == 13 || digitcounter == 16) && tempinitdigit == 4)
        {
             strcpy(result,"VISA\n") ;
        }

        else
        {
             strcpy(result,"INVALID\n") ;
        }

    }

    else
    {
        strcpy(result,"INVALID\n") ;
    }
    printf("%s\n", result) ;
}

Solution

  • I solved this problem 2 years ago from now. But I forgot to post the answer of this the question. So, I am putting my answer below. Hope this will be useful to beginner programmers.

    #include<cs50.h>
    #include<stdio.h>
    #include<stdbool.h>
    
    // Function prototype slot
    
    bool validity_checker(long long ccnum) ;
    int find_length_cc(long long ccnum) ;
    bool checksum(long long ccnum) ;
    void print_credit_card_name(long long ccnum) ;
    
    //Driver function to execute all those user-defined function
    
    int main()
    {
        long long ccnum;
    
        do
        {
            ccnum = get_long("Enter your credit card number: \n") ;
        }
        while (ccnum <= 0) ;
    
        if (validity_checker(ccnum))
        {
            print_credit_card_name(ccnum) ;
        }
        else
        {
            printf("INVALID\n") ;
        }
    }
    
    //Creating function body which will be called in the main function
    
    bool validity_checker(long long ccnum)
    {
        int len = find_length_cc(ccnum) ;
        return ((len == 13 || len == 15 || len == 16) && checksum(ccnum)) ;  // this will return if true
    
    }
    
    int find_length_cc(long long ccnum)
    {
        int len = 0 ;
        while (ccnum != 0)
        {
            ccnum = ccnum / 10 ;
            len++ ;
        }
        return len ;
    }
    
    bool checksum(long long ccnum)
    {
        int sum = 0 ;
        long long tempccnum = ccnum ;
    
        //Case-01(Weren't multiplied by 2): will start it's work from the last
    
        while (tempccnum > 0)
        {
            int lastdigit = tempccnum % 10 ; // accessing the last digit
            sum = sum + lastdigit ;
            tempccnum = tempccnum / 100 ;
        }
    
        // Case-02(Multiplication every other digit by 2):
    
        tempccnum = ccnum / 10 ; //removing the last digit
        while (tempccnum > 0)
        {
            int secondlastdigit = (tempccnum % 10) ;
            int tempmultiply = secondlastdigit * 2 ;
            // for multiple digits, this expression gives us their individual sum and adds with the total sum of cc
            sum = sum + (tempmultiply % 10) + (tempmultiply / 10)  ;
            //This will allow us to move and access two digits over
            tempccnum = tempccnum / 100 ;
        }
    
        return (sum % 10) == 0 ;
    }
    
    void print_credit_card_name(long long ccnum)  // First two digits checking
    {
        // 34e13 is first two digits and followed by 13 zeros as AMEX is 15 digits long
        if ((ccnum >= 34e13 && ccnum < 35e13) || (ccnum >= 37e13 && ccnum < 38e13))
        {
            printf("AMEX\n") ;
        }
    
        else if (ccnum >= 51e14 && ccnum < 56e14)
        {
            printf("MASTERCARD\n") ;
        }
    
        else if ((ccnum >= 4e12 && ccnum < 5e12) || (ccnum >= 4e15 && ccnum < 5e15))
        {
            printf("VISA\n") ;
        }
    
        else
        {
            printf("INVALID\n") ;
        }
    
    }