Created
April 20, 2020 20:14
-
-
Save ab-gh/8b74183815058b2348f37c027c59989c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <cs50.h> | |
// Prototypes | |
long get_card_no(void); | |
bool checksum_pass(long card_no); | |
string get_card_type(long card_no); | |
// Main | |
int main(void) | |
{ | |
// Prompt the user for the card number | |
long card_no = get_card_no(); | |
// a card number with invalid digits will return -1 and this be invalid | |
if (card_no < 0) | |
{ | |
printf("INVALID\n"); | |
} | |
// If it passes the checksum | |
else if (checksum_pass(card_no) == true) | |
{ | |
// Get the card type and print it | |
printf("%s", get_card_type(card_no)); | |
} | |
else | |
{ | |
// Fails the checksum | |
printf("INVALID\n"); | |
} | |
} | |
string get_card_type(long card_no) | |
{ | |
// Setting up variables | |
int first_digit = 0; | |
int second_digit = 0; | |
int third_digit = 0; | |
long working_card_no = card_no; | |
long multiplier = 1; | |
int working_digit; | |
// Loop | |
do | |
{ | |
// Calculate the latest digit | |
working_digit = (card_no / multiplier) % 10; | |
working_card_no = working_card_no / 10; | |
multiplier = multiplier * 10; | |
// Bump the storage of the last 3 over by one | |
first_digit = second_digit; | |
second_digit = third_digit; | |
third_digit = working_digit; | |
} | |
// Until the numbers are empty | |
while (working_card_no > 0); | |
// Swap third and first | |
int leading_digit = third_digit; | |
// If AMEX card | |
if (leading_digit == 3 && (second_digit == 4 || second_digit == 7)) | |
{ | |
return "AMEX\n"; | |
} | |
// If MASTERCARD card | |
else if (leading_digit == 5 && (second_digit <= 5 && second_digit > 0)) | |
{ | |
return "MASTERCARD\n"; | |
} | |
// If VISA card | |
else if (leading_digit == 4) | |
{ | |
return "VISA\n"; | |
} | |
// Else it is invalid | |
else | |
{ | |
return "INVALID\n"; | |
} | |
} | |
// Get and check the card number | |
long get_card_no(void) | |
{ | |
long card_no; | |
card_no = get_long("What is the card number?\n> "); | |
// if it is over 16 digits under 13 digits 14 digits, reject it | |
if (card_no > 10000000000000000 || card_no < 999999999999 || (99999999999999 < card_no && card_no < 100000000000000)) | |
{ | |
// It is invalid | |
return -1; | |
} | |
return card_no; | |
} | |
// Returns true if checksum is passed | |
bool checksum_pass(long card_no) | |
{ | |
// Setup variables | |
long working_card_no = card_no; | |
bool multiply_by_two = false; | |
long multiplier = 1; | |
int working_digit; | |
int twos_sum = 0; | |
int ones_sum = 0; | |
int totals_sum = 0; | |
int check_digit; | |
do | |
{ | |
// set working digit to the final digit in working number | |
working_digit = (card_no / multiplier) % 10; | |
// update working number | |
working_card_no = working_card_no / 10; | |
// every other digit | |
if (multiply_by_two) | |
{ | |
// multiply every other digit by two | |
int step_result = working_digit * 2; | |
// is this result two digits? | |
if (step_result > 9) | |
{ | |
// take the first digit | |
int part_sum = step_result % 10; | |
// add the second digit | |
part_sum = part_sum + ((step_result / 10) % 10); | |
// add to the sum of the digits multiplied | |
twos_sum = twos_sum + part_sum; | |
} | |
// if not, just add | |
else | |
{ | |
twos_sum = twos_sum + step_result; | |
} | |
} | |
// digits not multiplied | |
else | |
{ | |
// just add to the total | |
ones_sum = ones_sum + working_digit; | |
} | |
// flipflop for multiplying by 1 or 2 | |
multiply_by_two = !multiply_by_two; | |
// update multiplier | |
multiplier = multiplier * 10; | |
} | |
// stop when there are no more card digits | |
while (working_card_no > 0); | |
// get the total sum | |
totals_sum = twos_sum + ones_sum; | |
// get the check digit | |
check_digit = totals_sum % 10; | |
// printf("check digit: %i\n", check_digit); | |
if (check_digit == 0) | |
{ | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment