# Credit

A credit (or debit) card, of course, is a plastic card with which you can pay for goods and services. Printed on that card is a number thatâs also stored in a database somewhere, so that when your card is used to buy something, the creditor knows whom to bill. There are a lot of people with credit cards in this world, so those numbers are pretty long: American Express uses 15-digit numbers, MasterCard uses 16-digit numbers, and Visa uses 13- and 16-digit numbers. And those are decimal numbers (0 through 9), not binary, which means, for instance, that American Express could print as many as 10^15 = 1,000,000,000,000,000 unique cards! (Thatâs, um, a quadrillion.)

Actually, thatâs a bit of an exaggeration, because credit card numbers actually have some structure to them. All American Express numbers start with 34 or 37; most MasterCard numbers start with 51, 52, 53, 54, or 55 (they also have some other potential starting numbers which we wonât concern ourselves with for this problem); and all Visa numbers start with 4. But credit card numbers also have a âchecksumâ built into them, a mathematical relationship between at least one number and others. That checksum enables computers (or humans who like math) to detect typos (e.g., transpositions), if not fraudulent numbers, without having to query a database, which can be slow. Of course, a dishonest mathematician could certainly craft a fake number that nonetheless respects the mathematical constraint, so a database lookup is still necessary for more rigorous checks.

## Luhnâs Algorithm

So whatâs the secret formula? Well, most cards use an algorithm invented by Hans Peter Luhn of IBM. According to Luhnâs algorithm, you can determine if a credit card number is (syntactically) valid as follows:

1. Multiply every other digit by 2, starting with the numberâs second-to-last digit, and then add those productsâ digits together.
2. Add the sum to the sum of the digits that werenât multiplied by 2.
3. If the totalâs last digit is 0 (or, put more formally, if the total modulo 10 is congruent to 0), the number is valid!

Thatâs kind of confusing, so letâs try an example with Davidâs Visa: 4003600000000014.

1. For the sake of discussion, letâs first underline every other digit, starting with the numberâs second-to-last digit:

4003600000000014

Okay, letâs multiply each of the underlined digits by 2:

1â˘2 + 0â˘2 + 0â˘2 + 0â˘2 + 0â˘2 + 6â˘2 + 0â˘2 + 4â˘2

That gives us:

2 + 0 + 0 + 0 + 0 + 12 + 0 + 8

Now letâs add those productsâ digits (i.e., not the products themselves) together:

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

2. Now letâs add that sum (13) to the sum of the digits that werenât multiplied by 2 (starting from the end):

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

3. Yup, the last digit in that sum (20) is a 0, so Davidâs card is legit!

So, validating credit card numbers isnât hard, but it does get a bit tedious by hand. Letâs write a program.

## Implementation Details

In a file called `credit.c` in a `~/pset1/credit/` directory, write a program that prompts the user for a credit card number and then reports (via `printf`) whether it is a valid American Express, MasterCard, or Visa card number, per the definitions of eachâs format herein. So that we can automate some tests of your code, we ask that your programâs last line of output be `AMEX\n` or `MASTERCARD\n` or `VISA\n` or `INVALID\n`, nothing more, nothing less. For simplicity, you may assume that the userâs input will be entirely numeric (i.e., devoid of hyphens, as might be printed on an actual card). But do not assume that the userâs input will fit in an `int`! Best to use `get_long` from CS50âs library to get usersâ input. (Why?)

Consider the below representative of how your own program should behave when passed a valid credit card number (sans hyphens).

``````\$ ./credit
Number: 4003600000000014
VISA
``````

Now, `get_long` itself will reject hyphens (and more) anyway:

``````\$ ./credit
Number: 4003-6000-0000-0014
Number: foo
Number: 4003600000000014
VISA
``````

But itâs up to you to catch inputs that are not credit card numbers (e.g., a phone number), even if numeric:

``````\$ ./credit
Number: 6176292929
INVALID
``````

Test out your program with a whole bunch of inputs, both valid and invalid. (We certainly will!) Here are a few card numbers that PayPal recommends for testing.

If your program behaves incorrectly on some inputs (or doesnât compile at all), time to debug!

### How to Test Your Code

You can also execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!

``````check50 cs50/problems/2020/summer/credit
``````

Execute the below to evaluate the style of your code using `style50`.

``````style50 credit.c
``````

## How to Submit

Execute the below, logging in with your GitHub username and password when prompted. For security, youâll see asterisks (`*`) instead of the actual characters in your password.

``````submit50 cs50/problems/2020/summer/credit
``````