user11004300
user11004300

Reputation:

Wanted to check if a credit card number is valid or not

I wanted to check if a credit card number is valid or not but when i run the code, every number I give as input, the output comes as invalid.

The example given below is what I should i do.

Example with David’s Visa: 4003600000000014.

For the sake of discussion, let’s first underline every other digit, starting with the number’s second-to-last digit:

4003600000000014

  1. Okay, let’s multiply each of the underlined digits by 2:

1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2

That gives us:

2 + 0 + 0 + 0 + 0 + 12 + 0 + 8

  1. Now let’s add those products’ digits (i.e., not the products themselves) together:

2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13

  1. Now let’s add that sum (13) to the sum of the digits that weren’t multiplied by 2 (starting from the end):

13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20

  1. , the last digit in that sum (20) is a 0, so David’s card is legit!

#include <stdio.h>

int main()
{

    int no;
    printf("Visa number: ");`
    scanf("%d", &no);

    int d_1, d_2, d_3, d_4, d_5, d_6, d_7, d_8, d_9, d_10, d_11, d_12, d_13, d_14, d_15;

    d_15 = no%10;
    d_14 = ((no%100)/10)*2;
    d_13 = (no%1000)/100;
    d_12 = ((no%10000)/1000)*2;
    d_11 = (no%100000)/10000;
    d_10 = ((no%1000000)/100000)*2;
    d_9 = (no%10000000)/1000000;
    d_8 = ((no%100000000)/10000000)*2;
    d_7 = (no%1000000000)/100000000;
    d_6 = ((no%10000000000)/1000000000)*2;
    d_5 = (no%100000000000)/10000000000;
    d_4 = ((no%1000000000000)/100000000000)*2;
    d_3 = (no%10000000000000)/1000000000000;
    d_2 = ((no%100000000000000)/10000000000000)*2;
    d_1 = (no%1000000000000000)/100000000000000;

    int d[7] = {d_2, d_4, d_6, d_8, d_10, d_12, d_14};

    int n,add;

    for (n=1; n<=7; n++)
        if(d[n]>10)
        {
            d[n] = (d[n]%10);
            d[(15-n)+1] = ((d[n]%100)/10);
            int sum=0;
            for (int i=0; i<7; i++)
                sum += d[i];
        }
        else
        {
            add = d_14 + d_12 + d_10 + d_8 + d_6 + d_4 + d_2;
        }

    int sum = add + d_15 + d_13 + d_11 + d_9 + d_7 + d_5 + d_3 + d_1;

    if ((sum % 10) == 0)
    {
        printf("%s\n", "The card is valid");
    }
    else
    {
        printf("%s\n", "The card is invalid");
    }
}

Upvotes: 0

Views: 1592

Answers (3)

Martins Olarinde
Martins Olarinde

Reputation: 1

Consider declaring the user input as a long long data type so as to store up to 16 digits.

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

int main(void) 
    {
    // Prompt for Input
    long long n;
    do
    {
        n = get_long_long("Number: ");
    }
    while (n < 0);

    // Calculate Checksum
    int l;
    int m;
    int sum;
    long long first = n;
    long long first_two = n;
    int f = 0;
    int p = 0;
    int a = 0;
    int z = 0;
    int y = 0;
    int x = 0;
    do
    {
        l = n % 10;
        a++;

        n = n / 10;

        if (a % 2 == 1)
        {
            z = z + l;
        }

        if (a % 2 == 0)
        {
            if ((2 * l) > 9)
            {
                m = (2 * l) % 10;
                f = (2 * l) / 10;
                p = p + f + m;
            }
            else
            {
                x = x + (2 * l);
            }

            y = p + x;
        }
    }
    while (n > 0);

    sum = z + y; // checksum value

    // Check for card length and starting digits

    while (first_two > 99)
    {
        first_two = first_two / 10;
    }

    while (first > 9)
    {
        first = first / 10;
    }

    // Print Card name or Invalid

    if ((sum % 10 == 0) && (a == 15) && ((first_two == 34) || (first_two == 37)))
    {
        printf("AMEX\n");
    }

    else if ((sum % 10 == 0) && (a == 16) && ((first_two > 50) && (first_two < 56)))
    {
        printf("MASTERCARD\n");
    }

    else if ((sum % 10 == 0) && (a == 13 || a == 16) && (first == 4))
    {
        printf("VISA\n");
    }

    else
    {
        printf("INVALID\n");
    }
}

Upvotes: 0

Aung Khant Ko Ko
Aung Khant Ko Ko

Reputation: 1

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

long credit;

int getting_the_final_total_number (void);
void checking_which_kind (void);

int main(void)
{
   credit = get_long("Number: ");

   int i = 0;
   long number_count = credit;

   //finding how many numbers are there.
   while(number_count > 0)
   {
      number_count /= 10;
      i++;
   }

   //we use and because (using or make once true, the code block will work and always telling INVALID)

   if(i != 13 && i != 15 && i != 16)
   {
      printf("INVALID\n");
      return 0;
   }

   
   int total = getting_the_final_total_number(); //adding sum_1 and sum_2


   if(total % 10 != 0)
   {
      printf("INVALID\n");
      return 0;
   }

   checking_which_kind();

}

//assigning the credit to another variable for the loop
int getting_the_final_total_number (void)
{
   long credit_one = credit;

   int mod_1;
   int mod_2;

   int sum_1 = 0;

   int m;
   int d;
   int sum_2 = 0;

   do
   {
      //cutting the number into two pieces with all the last numbers and all the second-last-numbers

      //cutting the last numbers.
      mod_1 = credit_one % 10;
      credit_one = credit_one / 10;

      sum_1 += mod_1;

      //cutting the second-last-numbers.
      mod_2 = credit_one % 10;
      credit_one = credit_one / 10;

      //doubling the mod_2 (the second-last-numbers)
      mod_2 = mod_2 * 2;

      //making them into one number (if there is 16 or 18 in the product then make them 1 and 6 or 1 and 8. After that add them all together ).

      m = mod_2 % 10;  //This is for only one standing numer like 1 or 2 or 9 etc (but no 12 or 14 or 16)
      d = mod_2 / 10;    //This is for ten's digit to make sure to become ONE standing digit

      sum_2 = sum_2 + m + d;
   }
   while(credit_one > 0);

   return sum_1 + sum_2;
}

 //checking the first two number of credit
void checking_which_kind (void)
{
   long cc = credit;

   do
   {
    cc = cc / 10;
   }
   while(cc > 100);

   if(cc / 10 == 5 && (cc % 10 > 0 || cc % 10 < 6))
   {
      printf("MASTERCARD\n");
   }
   else if(cc / 10 == 3 && (cc % 10 == 4 || cc % 10 == 7))
   {
      printf("AMERICAN EXPRESS\n");
   }
   else if(cc / 10 == 4 && cc % 10 >= 0)
   {
      printf("VISA\n");
   }
   else
   {
      printf("ERROR");
   }
}

Upvotes: 0

chux
chux

Reputation: 154572

every number I give as input, the output comes as invalid.

Too big

OP's int is likely 32-bit.

Reading text input that would attempt to form an int outside the int range is undefined behavior. Rest of code is irrelevant.

int no;
scanf("%d", &no);  // attempt to read "4003600000000014" leads to UB.

Consider reading user input into a string first and then process the characters. @Weather Vane

char buf[100];

if (fgets(buf, sizeof buf, stdin)) {
  int i;
  sum[2] = { 0, 0 };  // sums of even indexed digits and odd indexed digits.
  // Note: only 1 sum really needed, but using 2 sums to mimic OP's approach

  for (i = 0; isdigit((unsigned char) buf[i]); i++) {
    digit = buf[i] - '0';
    if (i%2 == 0) {
      digit *= 2;
      if (digit >= 10) {
        digit = (digit/10 + digit%10);  
      }
    } 
    sum[i%2] += digit;
  }


  // reject bad input: too long or missing expected end
  if (i > 16 || (buf[i] != '\n' && buf[i] != '\0')) {
    puts("Bad input");
  } else {
    // pseudo code to not give everything away.
    // do math on sum[0], sum[1]
    // if as expected --> success 
  }
}

Upvotes: 2

Related Questions