Credit.C do Papis

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
3.1 kB
1
Indexable
Never
// by hBarcellos to CS50x. Im doing this in order to incentivate my son to do the same! ;)
#include <cs50.h>
#include <stdio.h>

int main(void)
{
    long lNumber;

    lNumber = get_long("Number: ");
    if ((lNumber<999999999999)||(lNumber>9999999999999999)) {         //Let's forget numbers with less than 13 digits
        printf("INVALID\n");
        return (0); //was error 4
    }
    //Diners credit cards have 14 digits, but, for some reason this test does not allow Diners credit cards
    if ((lNumber>9999999999999)&&(lNumber<=99999999999999)) {
        printf("INVALID\n");
        return (0);             // 1 = Invalid Number Format
    }

    //Le'ts calculate the checksum

    long l1 = lNumber;
    long l2;
    int nDig,nSum1=0,nSum2=0;
    unsigned int nDigits=0;
    bool bPhase=1;

    //main Loop
    do {
        l2 = (l1/10)*10;
        nDig = l1-l2;

        // Ill keep alternating the phases. Phase 1 = just sums the digits
        if (bPhase) {
            nSum1+=nDig;
            bPhase=0;
        } else {                    // Phase = 0 : Add digits multiplied by 2
            int nTmp = nDig*2;
            if (nTmp>9) {           // Unless the multiplication is >9
                nTmp-=10;           // then, I subtract 10 (cant be higher than 18)
                nSum2++;            // and increase the sum of an extra 1
            }
            nSum2+=(nTmp);
            bPhase=1;
        }
        //printf ("=> nDig = %d | l1 = %ld | l2 = %ld\n",nDig,l1,l2);
        l1 = l2/10;
        nDigits++;
    } while (l1>0);

    int nCheck = (nSum1+nSum2) - ((nSum1+nSum2)/10)*10;

//printf("nSum1=%d | nSum2= %d | Total = %d | nCheck = %d\n",nSum1,nSum2,nSum1+nSum2,nCheck);
//printf("Digits = %d\n",nDigits);

    if (nCheck) {
        printf("INVALID\n");
        return (0);             // 2 = Invalid Checksum
    }

    // Now the final verification (might be doable to do it above, but...)
    int nTipo=0;
    switch (nDigits)
    {
        case 13:                                    // Visa 13 digits
            nSum1 = lNumber / 1000000000000;
            if (nSum1==4) {
                nTipo=1;
                printf("VISA\n");
                return (0);
            }
            break;
        case 15:                                    // American Express
            nSum1 = lNumber / 10000000000000;
            if ((nSum1==34)||(nSum1==37)) {
                nTipo=2;
                printf("AMEX\n");
                return (0);
            }
            break;
        case 16:
            nSum1 = lNumber / 100000000000000;     // Visa/MC 16 digits
            if ((nSum1>=40)&&(nSum1<=49)) {
                nTipo = 3; // Visa
                printf("VISA\n");
                return (0);
            }
            if ((nSum1>=51)&&(nSum1<=55)) {
                nTipo = 4; // Mastercard
                printf("MASTERCARD\n");
                return (0);
            }
            break;
    }

    printf("INVALID\n");
    return (0);                              // Invalid first one/two numbers


}