Skip to content

Instantly share code, notes, and snippets.

@ab-gh
Created April 20, 2020 20:14
Show Gist options
  • Save ab-gh/8b74183815058b2348f37c027c59989c to your computer and use it in GitHub Desktop.
Save ab-gh/8b74183815058b2348f37c027c59989c to your computer and use it in GitHub Desktop.
#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