This project implements a credit card number validator in C, fulfilling the requirements for CS50's Problem Set 1. The solution validates credit card numbers using Luhn's algorithm and identifies the card issuer based on industry-standard patterns.
Project Requirements
- Validate credit card numbers using Luhn's algorithm
- Identify card issuer (Visa, MasterCard, American Express)
- Handle different card lengths (13, 15, 16 digits)
- Provide clear output (VALID/INVALID)
Step 1: Prompting User for Input
We start by prompting the user to enter a positive credit card number using the get_long
function
from the CS50 library. This ensures we capture the full number without truncation.
// Prompt user for credit card number
long number;
do
{
number = get_long("Number: ");
}
while (number < 1);
Step 2: Counting the Length of the Number
We need to count the number of digits to help identify the card type. Different card issuers use different lengths:
American Express
- 15 digits
- Starts with 34 or 37
MasterCard
- 16 digits
- Starts with 51-55
Visa
- 13 or 16 digits
- Starts with 4
// Count number of digits
int length_count(long number)
{
int length = 0;
while (number > 0)
{
number /= 10; // Remove last digit
length++; // Increment count
}
return length;
}
Step 3: Validating with Luhn's Algorithm
Luhn's algorithm is used to validate the credit card number. The process:
Algorithm Steps
- Starting from the second-to-last digit, multiply every other digit by 2
- Add the digits of each product together
- Add this sum to the sum of the digits that weren't multiplied by 2
- If the total modulo 10 is 0, the card number is valid
// Validate with Luhn's algorithm
char check_valid(long number)
{
int sum1 = 0; // Sum of digits not multiplied
int sum2 = 0; // Sum of digits from multiplied numbers
int multiply = 0;
while (number > 0)
{
// Add last digit to sum1
sum1 += number % 10;
number /= 10;
// Multiply next digit by 2
multiply = number % 10;
multiply *= 2;
// Add digits of product to sum2
while (multiply > 0)
{
sum2 += multiply % 10;
multiply /= 10;
}
number /= 10;
}
// Check if total ends with 0
int total = sum1 + sum2;
return (total % 10 == 0) ? 'Y' : 'N';
}
Step 4: Identifying Card Type
After validation, we identify the card issuer based on length and starting digits:
// Identify card issuer
string card_type(long number, int length)
{
int prefix;
// Check American Express (15 digits)
if (length == 15)
{
prefix = number / 10000000000000; // First two digits
if (prefix == 34 || prefix == 37)
return "AMEX";
}
// Check 16-digit cards
else if (length == 16)
{
prefix = number / 100000000000000; // First two digits
// MasterCard (51-55)
if (prefix >= 51 && prefix <= 55)
return "MASTERCARD";
// Visa (starts with 4)
if (prefix / 10 == 4)
return "VISA";
}
// Check Visa (13 digits)
else if (length == 13)
{
prefix = number / 1000000000000; // First digit
if (prefix == 4)
return "VISA";
}
return "INVALID";
}
Step 5: Full Implementation
The complete solution integrates all components to validate and identify credit cards:
#include <stdio.h>
#include <cs50.h>
// Function prototypes
int length_count(long number);
char check_valid(long number);
string card_type(long number, int length);
int main(void)
{
// Prompt user for credit card number
long number;
do
{
number = get_long("Number: ");
}
while (number < 1);
// Calculate number length
int length = length_count(number);
// Validate using Luhn's algorithm
char valid = check_valid(number);
// Output result
if (valid == 'Y')
{
string card = card_type(number, length);
printf("%s\n", card);
}
else
{
printf("INVALID\n");
}
}
// Count number of digits
int length_count(long number)
{
int length = 0;
while (number > 0)
{
number /= 10;
length++;
}
return length;
}
// Validate with Luhn's algorithm
char check_valid(long number)
{
int sum1 = 0; // Sum of digits not multiplied
int sum2 = 0; // Sum of digits from multiplied numbers
int multiply = 0;
while (number > 0)
{
sum1 += number % 10;
number /= 10;
multiply = number % 10;
multiply *= 2;
while (multiply > 0)
{
sum2 += multiply % 10;
multiply /= 10;
}
number /= 10;
}
int total = sum1 + sum2;
return (total % 10 == 0) ? 'Y' : 'N';
}
// Identify card issuer
string card_type(long number, int length)
{
int prefix;
if (length == 15)
{
prefix = number / 10000000000000;
if (prefix == 34 || prefix == 37)
return "AMEX";
}
else if (length == 16)
{
prefix = number / 100000000000000;
if (prefix >= 51 && prefix <= 55)
return "MASTERCARD";
if (prefix / 10 == 4)
return "VISA";
}
else if (length == 13)
{
prefix = number / 1000000000000;
if (prefix == 4)
return "VISA";
}
return "INVALID";
}
Key Considerations
- Input Validation: The program ensures only positive numbers are accepted
- Edge Cases: Handles invalid lengths and prefixes appropriately
- Algorithm Accuracy: Correctly implements Luhn's algorithm for validation
- Performance: Efficiently processes even large numbers
- Readability: Well-structured code with clear function separation