Skip to content

Task 5: Credit

A person holding credit cards

Problem to solve

A credit or debit card number identifies an account when a card is used to pay for goods or services. These numbers are long: American Express uses 15 digits, MasterCard uses 16 digits, and Visa uses 13 or 16 digits.

Card numbers also have a defined structure:

Card type Number of digits Begins with
American Express 15 34 or 37
MasterCard 16 51, 52, 53, 54, or 55
Visa 13 or 16 4

They also contain a checksum: a mathematical relationship among their digits that can help detect typing errors. A valid checksum does not prove that a card number is real; an actual payment system would still need to check its database.

In a file named credit.c inside a folder named credit, implement a C program that checks a card number's checksum and identifies its card type.

Never test this program with a real card number. Use only the example numbers provided on this page.

Luhn's algorithm

Use Luhn's algorithm to determine whether the checksum is valid:

  1. Starting with the second-to-last digit, multiply every other digit by 2.
  2. Add the individual digits of those products. For example, a product of 12 contributes 1 + 2.
  3. Add the digits that were not multiplied by 2.
  4. Add the two sums. If the total ends in 0, the checksum is valid.

Worked example

Consider the Visa test number 4003600000000014.

Starting from the second-to-last digit and moving left, the digits to double are:

1, 0, 0, 0, 0, 6, 0, 4

Doubling them gives:

2, 0, 0, 0, 0, 12, 0, 8

Add the individual digits of those products:

2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13

Then add the digits that were not doubled:

13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20

Because 20 ends in 0, the number passes the checksum. It also begins with 4 and contains 16 digits, so the program should identify it as Visa.

Implementation requirements

  • Prompt the user with Number:.
  • Store the input in an unsigned long long; a card number may be too large for an int.
  • Read the number with scanf and the %llu format specifier.
  • Apply Luhn's algorithm before identifying the card type.
  • Print exactly one of AMEX, MASTERCARD, VISA, or INVALID, followed by a new line.
  • Print INVALID when the checksum fails or when the length and starting digits do not match one of the supported card types.

You may assume that the input is a positive integer with no spaces, hyphens, or leading zeroes.

For example:

$ ./credit
Number: 4003600000000014
VISA

A numeric input can pass through scanf but still be too short to be a card number:

$ ./credit
Number: 6176292929
INVALID
Hints

The remainder operator can give you the last digit of a number: number % 10. Integer division can remove that digit: number / 10.

Keep the original number unchanged if you also need it later to check its length and starting digits.

It may be easier to solve this in three stages: calculate the checksum, determine the number of digits and prefix, and then print the result.

Compile and test

From the credit folder, run:

cc credit.c -o credit
./credit

If your system provides gcc instead of cc, use gcc credit.c -o credit.

Test your program with these example numbers:

Number Expected output
378282246310005 AMEX
5555555555554444 MASTERCARD
4003600000000014 VISA
4003600000000015 INVALID
6176292929 INVALID

After testing, return to the Problem Set 1 overview.