136 lines
3.2 KiB
C
136 lines
3.2 KiB
C
|
#include <cs50.h>
|
||
|
#include <stdio.h>
|
||
|
#include <math.h>
|
||
|
|
||
|
void invalid(void);
|
||
|
void card_check(long user_input, int nDigits);
|
||
|
int start_digits(long);
|
||
|
bool luhn_algo(long user_input, int nDigits);
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
//takes user input and check if the value is positive number
|
||
|
long user_input = get_long("Enter credit card number:");
|
||
|
if (user_input < 1)
|
||
|
{
|
||
|
invalid();
|
||
|
}
|
||
|
//calculates the lenght of input and if correct, continues with card_check
|
||
|
int nDigits = floor(log10(user_input)) + 1;
|
||
|
if (nDigits == 15 || nDigits == 13 || nDigits == 16)
|
||
|
{
|
||
|
card_check(user_input, nDigits);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
invalid();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//gives invalid output message to user
|
||
|
void invalid(void)
|
||
|
{
|
||
|
printf("INVALID\n");
|
||
|
}
|
||
|
|
||
|
int start_digits(long user_input)
|
||
|
{
|
||
|
while (user_input >= 100)
|
||
|
{
|
||
|
user_input /= 10;
|
||
|
}
|
||
|
return user_input;
|
||
|
}
|
||
|
|
||
|
//luhn algoritm to check validity of card number
|
||
|
bool luhn_algo(long user_input, int nDigits)
|
||
|
{
|
||
|
//creates array and sets first value to last digit of user input number
|
||
|
int n[nDigits];
|
||
|
n[0] = user_input % 10;
|
||
|
//loops through the remaining digits and stores them in the array as well (from back to the beginning)
|
||
|
int i = 1;
|
||
|
while (user_input >= 1)
|
||
|
{
|
||
|
user_input /= 10;
|
||
|
n[i] = user_input % 10;
|
||
|
i++;
|
||
|
}
|
||
|
//creates another array and fills it with every other digit multiplied by 2, starting at 2nd to last position
|
||
|
int check_sum = 0;
|
||
|
int check_digits[nDigits / 2];
|
||
|
int j = 0;
|
||
|
for (i = 1; i < nDigits; i += 2)
|
||
|
{
|
||
|
check_digits[j] = n[i] * 2;
|
||
|
j++;
|
||
|
}
|
||
|
//creates sum of digits from array created above
|
||
|
for (i = 0; i < nDigits / 2; i++)
|
||
|
{
|
||
|
//neccessary check for values with more than 1 digit, to create sum of their digits
|
||
|
if (check_digits[i] > 9)
|
||
|
{
|
||
|
check_sum = check_sum + check_digits[i] % 10;
|
||
|
while (check_digits[i] > 9)
|
||
|
{
|
||
|
check_digits[i] /= 10;
|
||
|
}
|
||
|
check_sum = check_sum + check_digits[i];
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
check_sum = check_digits[i] + check_sum;
|
||
|
}
|
||
|
}
|
||
|
//adds sum of all digits that were not multiplied by 2 previously
|
||
|
for (i = 0; i < nDigits; i += 2)
|
||
|
{
|
||
|
check_sum = n[i] + check_sum;
|
||
|
}
|
||
|
//checks if the last number of final check_sum is 0 and returns true or false
|
||
|
if (check_sum % 10 == 0)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
invalid();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//checks for the beginning numbers and branches into correct card provider
|
||
|
void card_check(long user_input, int nDigits)
|
||
|
{
|
||
|
int beginning = start_digits(user_input);
|
||
|
if (beginning == 34 || beginning == 37)
|
||
|
{
|
||
|
//check validity of card by using luhn alghoritm
|
||
|
if (luhn_algo(user_input, nDigits))
|
||
|
{
|
||
|
printf("AMEX\n");
|
||
|
}
|
||
|
}
|
||
|
else if (beginning > 39 && beginning < 50)
|
||
|
{
|
||
|
if (luhn_algo(user_input, nDigits))
|
||
|
{
|
||
|
printf("VISA\n");
|
||
|
}
|
||
|
}
|
||
|
else if (beginning > 50 && beginning < 56)
|
||
|
{
|
||
|
if (luhn_algo(user_input, nDigits))
|
||
|
{
|
||
|
printf("MASTERCARD\n");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
invalid();
|
||
|
}
|
||
|
}
|