// 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
}