/**************************************************
* credit.c *
* *
* CS50 *
* *
* Prompts the user for a credit card number and *
* *
* determines the type of the card. *
*************************************************/
#include <cs50.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
/* enumeration containing the result of the test on the credit card number ...
frankly I do not know why I decided to do it that way ... */
enum credit_card_type {AMEX, MASTERCARD, VISA, INVALID} type;
// used to obtain a string equivalent of an enumerated value
char card_type[][26] = {"AMEX", "MASTERCARD", "VISA", "INVALID"};
void is_it_legit(long long int credit_card_number, int credit_card_number_length);
void what_kinda_credit_card(long long int credit_card_number, int credit_card_number_length);
int
main(void)
{
// used to determine the length of the credit card number
char temp_credit_card_number[17];
// prompt the user for a credit card number
printf("Enter a credit card number: "); long long int credit_card_number = GetLongLong();
// "credit_card_number" converted to a string in order to determine its length
snprintf(temp_credit_card_number
, 17, "%lld", credit_card_number
); int credit_card_number_length
= strlen(temp_credit_card_number
);
what_kinda_credit_card(credit_card_number, credit_card_number_length);
return 0;
}
/*
* Test the legitimacy of the credit card number.
*/
void
is_it_legit(long long int credit_card_number, int credit_card_number_length)
{
long long int every_other_digit;
long long int left_out_digit;
int products_digits_sum = 0;
int left_out_digits_sum = 0;
/* isolate every other digits starting with the number's second-to-last digit,
multiply it by 2, and then add those products' digits together */
for (int i = credit_card_number_length - 2; i > -1; i -= 2 ) {
every_other_digit
= ((long long int) (credit_card_number
/ pow(10, i
))) % 10; products_digits_sum += ((every_other_digit * 2) / 10) + ((every_other_digit * 2) % 10);
}
// isolate the digits which weren't multiplied by 2, and then add these digits together
for (int i = credit_card_number_length - 1; i > -1; i -= 2) {
left_out_digit
= ((long long int) (credit_card_number
/ pow(10, i
))) % 10; left_out_digits_sum += left_out_digit;
}
int final_sum = products_digits_sum + left_out_digits_sum;
// test weather the last digit of "final_sum" is 0 or not
if (final_sum % 10 == 0)
// print type of credit card
printf("%s\n", card_type
[type
]); else
// print invalid message
}
/*
* Determine the type of the credit card.
*/
void
what_kinda_credit_card(long long int credit_card_number, int credit_card_number_length)
{
// these variables store the first or two first digits of a credit card number.
int visa_first_digit_13
= (credit_card_number
/ pow(10, 12)); int visa_first_digit_16
= (credit_card_number
/ pow(10, 15)); int amex_two_first_digits
= (credit_card_number
/ pow(10, 13)); int mastercard_two_first_digits
= (credit_card_number
/ pow(10, 14));
switch (credit_card_number_length) {
case 13:
// VISA ?
if (visa_first_digit_13 == 4) {
/* the integer value "2" is assigned to the variable "result".
In the enumeration "credit_card_type" the integer constant 2
is named VISA */
type = 2;
is_it_legit(credit_card_number, credit_card_number_length);
} else
// print invalid message
break;
case 15:
// AMEX ?
if ((amex_two_first_digits == 34) || (amex_two_first_digits == 37)) {
type = 0;
is_it_legit(credit_card_number, credit_card_number_length);
} else
break;
case 16:
// VISA ?
if (visa_first_digit_16 == 4) {
type = 2;
is_it_legit(credit_card_number, credit_card_number_length);
// MASTERCARD ?
} else if ((mastercard_two_first_digits == 51)
|| (mastercard_two_first_digits == 52)
|| (mastercard_two_first_digits == 53)
|| (mastercard_two_first_digits == 54)
|| (mastercard_two_first_digits == 55)) {
type = 1;
is_it_legit(credit_card_number, credit_card_number_length);
} else
break;
default:
}
}