Created
March 17, 2021 18:21
-
-
Save YenHub/2fe2aeeef3788fb56002e1126d5a9d8b to your computer and use it in GitHub Desktop.
Luhn's Algorithm in C
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> | |
string cardType; | |
// Prompt for a valid card number | |
long getCardNumber(void) | |
{ | |
long cardNumber; | |
cardNumber = get_long("Please enter the card number: "); | |
return cardNumber; | |
} | |
int getDigitCount(long n) | |
{ | |
int digits = 0; | |
while (n > 0) | |
{ | |
n /= 10; | |
digits++; | |
} | |
return digits; | |
} | |
int getFirstDigit(long n) | |
{ | |
while (n > 10) | |
{ | |
n /= 10; | |
} | |
return n; | |
} | |
int getFirstTwoDigits(long n) | |
{ | |
while (n > 100) | |
{ | |
n /= 10; | |
} | |
return n; | |
} | |
// Basic validation against known card types using digit count & card prefixes | |
bool digitCheck(long cardNumber) | |
{ | |
int cardDigits = getDigitCount(cardNumber); | |
int firstTwoDigits = getFirstTwoDigits(cardNumber); | |
int firstDigit = getFirstDigit(cardNumber); | |
switch (cardDigits) | |
{ | |
case 13: // Visa | |
if (firstDigit == 4) | |
{ | |
cardType = "VISA"; | |
return true; | |
} | |
case 16: // Visa & Mastercard | |
// Visa Cards begin with a 4 | |
if (firstDigit == 4) | |
{ | |
cardType = "VISA"; | |
return true; | |
} | |
// Master cards are 51, 52, 53, 54, or 55 | |
if (firstTwoDigits >= 51 && firstTwoDigits <= 55) | |
{ | |
cardType = "MASTERCARD"; | |
return true; | |
} | |
case 15: // Amex | |
// Amex cards only begin with 34 &37 | |
if (firstTwoDigits == 34 || firstTwoDigits == 37) | |
{ | |
cardType = "AMEX"; | |
return true; | |
} | |
} | |
return false; | |
} | |
bool cardRangeCheck(long cardNumber) | |
{ | |
int cardDigits = getDigitCount(cardNumber); | |
if (cardDigits < 13) return false; | |
if (cardDigits > 16) return false; | |
if (cardDigits == 14) return false; | |
return true; | |
} | |
bool luhnsCheck(long cardNumber) | |
{ | |
// Multiply every other digit by 2, starting with the number’s second-to-last digit then add those products’ digits together. | |
int count = 0; | |
int result = 0; | |
long odd_check = cardNumber; | |
while (odd_check > 0) | |
{ | |
if (count % 2 == 1) | |
{ | |
int value = (odd_check % 10) * 2; | |
int sum = 0; | |
while (value != 0) | |
{ | |
sum += value % 10; | |
value /= 10; | |
} | |
result += sum; | |
} | |
odd_check /= 10; | |
count++; | |
} | |
// Sum the result with each of the digits that weren’t multiplied by 2. | |
count = 0; | |
long even_check = cardNumber; | |
while (even_check > 0) | |
{ | |
if (count % 2 == 0) | |
{ | |
int value = (even_check % 10); | |
int sum = 0; | |
while (value != 0) | |
{ | |
sum += value % 10; | |
value /= 10; | |
} | |
result += sum; | |
} | |
even_check /= 10; | |
count++; | |
} | |
// If the total modulo 10 is congruent to 0, the number is valid! | |
return result % 10 == 0; | |
} | |
bool validateCard(long cardNumber) | |
{ | |
// Basic range check for the number of digits | |
if (cardRangeCheck(cardNumber) == false) return false; | |
// Check the digit length for known cards | |
if (digitCheck(cardNumber) == false) return false; | |
// Finally, run Luhn's Algorithm against the num check approved card number | |
if (luhnsCheck(cardNumber) == false) return false; | |
return true; | |
} | |
int main(void) | |
{ | |
// Prompt the user for a valid card number | |
long cardNumber = getCardNumber(); | |
// Validate the card | |
bool isValidCard = validateCard(cardNumber); | |
if (isValidCard) | |
{ | |
printf("%s\n", cardType); | |
} | |
else | |
{ | |
printf("INVALID\n"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment