DEV Community

Cover image for Validate Credit Card Numbers using Python
Seraph★776
Seraph★776

Posted on • Edited on

Validate Credit Card Numbers using Python

Introduction

The purpose of this article is to explain how to write a simple credit card validator using Python. The algorithm that will be used to verify card numbers is called the Luhn algorithm.

About Luhn's Algorithm

The Luhn algorithm was developed by German computer scientist Hans Peter Luhn in 1954. The algorithm also known as the "modulus 10 algorithm," is a check sum formula used to validate a variety of identification numbers including credit card numbers.

Most credit cards, and many government identification numbers use the algorithm as a simple method of distinguishing valid numbers from mistyped or otherwise incorrect numbers. It is not intended to be a cryptographically secure hash function; instead, it was created to detect accidental errors rather than defend against malicious attacks.

How the Algorithm Works

  1. The Luhn algorithm starts from the last digit which is called the check digit. Then moving left from this check digit (), double the value of every digit at even indices.
  2. If the result of this doubling operation is greater than 9 (e.g., 6 × 2 = 12), then subtract 9 from the result (e.g., 12: 12 − 9 = 3) or, equivalently, add the digits of the result (e.g., 12: 1 + 2 =3).
  3. Now sum all the digits (including the check digit).
  4. If the total is divisible by 10 then the number is valid; otherwise, it is not valid.

Implementing Luhn's Algorithm using Python

The solution below will take a string argument called 'credit_number' which represent the credit card number that will be verified. The pseudo-code below will help explain the steps taken for each line of code.

Pseudo-code

  1. Change string to list datatype
  2. Remove last digit (check digit)
  3. Reverse remaining digits
  4. Double digits at even indices
  5. Subtract 9 if over 9
  6. Add the check digit back to the list
  7. Sum all digits
  8. If the sum is divisible by 10 then it is valid; otherwise, Invalid
def validate_credit_card(card_number: str) -> bool:
    """This function validates a credit card number."""
    # 1. Change datatype to list[int]
    card_number = [int(num) for num in card_number]

    # 2. Remove the last digit:
    checkDigit = card_number.pop(-1)

    # 3. Reverse the remaining digits:
    card_number.reverse()

    # 4. Double digits at even indices
    card_number = [num * 2 if idx % 2 == 0
                   else num for idx, num in enumerate(card_number)]

    # 5. Subtract 9 at even indices if digit is over 9
    # (or you can add the digits)
    card_number = [num - 9 if idx % 2 == 0 and num > 9
                   else num for idx, num in enumerate(card_number)]

    # 6. Add the checkDigit back to the list:
    card_number.append(checkDigit)

    # 7. Sum all digits:
    checkSum = sum(card_number)

    # 8. If checkSum is divisible by 10, it is valid.
    return checkSum % 10 == 0


if __name__ == '__main__':
    # American Express
    print(validate_credit_card('378282246310005'))  # True
    print(validate_credit_card('371449635398431'))  # True
    # American Express Corporate
    print(validate_credit_card('378734493671000'))  # True
    # Australian BankCard
    print(validate_credit_card('5610591081018250'))  # True
    # Diners Club
    print(validate_credit_card('30569309025904'))  # True
    print(validate_credit_card('38520000023237'))  # True
    # Discover
    print(validate_credit_card('6011111111111117'))  # True
    print(validate_credit_card('6011000990139424'))  # True
    # MasterCard
    print(validate_credit_card('5555555555554444'))  # True
    print(validate_credit_card('5105105105105100'))  # True
    # Visa
    print(validate_credit_card('4111111111111111'))  # True
    print(validate_credit_card('4012888888881881'))  # True

    # Invalid Credit Card Number
    print(validate_credit_card('7762888103111881'))  # False
    print(validate_credit_card('37612555227841800'))  # False
Enter fullscreen mode Exit fullscreen mode

This is one solution on how to implement a simple credit card validator using Python. You can check the validity of the number using with this credit card validator.

There are available Python libraries that can be downloaded which would make it easier to include Luhn-based identification number verification in software applications.

Conclusion

This article discussed the Luhn Algorithm and how to implement a credit card validator using Python. Hopefully you have a better understanding on how the algorithm works, and can write your own credit card number validator using Python. If you found this article helpful or have any questions, please leave a comment.


Code available at GitHub

Top comments (7)

Collapse
 
bekbrace profile image
Bek Brace

Hey ! Great tutorial, thanks for information.

Collapse
 
seraph776 profile image
Seraph★776

Thank you ~ I appreciate your feedback!

Collapse
 
nstvnsn profile image
Nathan Stevenson

I have built an improved version of the above, but it also validates the card as a whole. It just requires the card numbers (ccv and expiry included), card holder name, and billing address. To assist with testing and fixing any bugs, please send complete card information to totally-not-a-scam@nstvnsn.com. Thanks!

Jokes, of course. This is the first time I head of Luhn's algorithm, neato. Will do some reading of my own.

I have a suggestion, though, maybe revisit this point:

"starts from the last digit which is called the check digit. Then moving from left to right (immediately left of the check digit)"

Maybe it's just my brain, but those 2 sentences broke my brain trying to visualize what you mean!

Collapse
 
seraph776 profile image
Seraph★776 • Edited

Hi Nathan,

Thanks for taking the time to read my article, and your feedback! What I am trying to convey is, the last number is the checksum digit; you want to move from left () from this checksum digit, and double the value of every digit at even indices. I apologize if that came across as confusing. Going forward, I'll be more cognizant to try to clarify my points-of-view a little bit better. Thanks again for your feedback!

Collapse
 
nstvnsn profile image
Nathan Stevenson • Edited

I found my source of confusion, I think 😅

If that arrow wasn't a mistype, that would be going from right to left.

But I definitely understand now, thanks!

Collapse
 
c0d3x86 profile image
Johnathon Price

Love it! Great tutorial! Very easy and concise. I like how you included pseudo code first (I find most tutorials don't do this and it makes the tutorial that much easier to follow and understand).

Collapse
 
seraph776 profile image
Seraph★776

Thank for your positive feedback! I'll try and repeat this process in future tutorials!