Back to Freecodecamp

Implement the Luhn Algorithm

curriculum/challenges/english/blocks/lab-luhn-algorithm/68507cadbf36aa089a84ce2d.md

latest4.7 KB
Original Source

--description--

The Luhn algorithm, also known as the "modulus 10" or "mod 10" algorithm, is a simple checksum formula used to validate a variety of identification numbers, like credit card numbers. These are the steps to validate a number using the Luhn algorithm:

  • Starting from the right, and excluding the rightmost digit (the check digit), double the value of every other digit.
  • If the result of doubling a digit is greater than 9, sum the digits to get a single digit. Alternatively, you can subtract 9 from the result.
  • Take the sum of all the digits including the check digit.
  • If the sum of all the digits is a multiple of 10, then the number is valid; else it is not valid.

Let's say we have the number 453914881. The steps to validate it using the Luhn algorithm would be:

md
Account number      4   5   3   9   1   4   8   8   1 
Double every other  4  10   3  18   1   8   8  16   1 
Sum 2-char digits   4   1   3   9   1   8   8   7   1 
  • Then sum all numbers, 4 + 1 + 3 + 9 + 1 + 8 + 8 + 7 + 1 = 42.
  • Since 42 is not a multiple of 10, the number is invalid.

In this lab, you will build a credit card validator using the Luhn algorithm.

Objective: Fulfill the user stories below and get all the tests to pass to complete the lab.

User Stories:

  1. You should define a function named verify_card_number that takes a string of digits (representing a card number) and verifies whether it is valid according to the Luhn algorithm.

  2. Within the verify_card_number function:

    • You should handle any dashes or spaces that may be present in the card number passed to it.
    • Return VALID! if the card number is valid; otherwise, return INVALID!.

When you complete the project, you should see the following messages depending on the input:

Card NumberMessage
453914889VALID!
4111-1111-1111-1111VALID!
1234 5678 9012 3456INVALID!

--hints--

You should have a function named verify_card_number.

js
({
    test: () => runPython(`
    assert _Node(_code).has_function('verify_card_number')
    `)
})

verify_card_number('453914889') should return VALID!.

js
({
    test: () => runPython(`
    assert verify_card_number('453914889') == 'VALID!'
    `)
})

verify_card_number('4111-1111-1111-1111') should return VALID!.

js
({
    test: () => runPython(`
    assert verify_card_number('4111-1111-1111-1111') == 'VALID!'
    `)
})

verify_card_number('453914881') should return INVALID!.

js
({
    test: () => runPython(`
    assert verify_card_number('453914881') == 'INVALID!'
    `)
})

verify_card_number('1234 5678 9012 3456') should return INVALID!.

js
({
    test: () => runPython(`
    assert verify_card_number('1234 5678 9012 3456') == 'INVALID!'
    `)
})

verify_card_number should return VALID! when called with a valid credit card number.

js
({
    test: () => runPython(`
    assert verify_card_number('4539 1488 0343 6467') == 'VALID!'
    assert verify_card_number('6011 1111 1111 1117') == 'VALID!'
    assert verify_card_number('3782-822463-10005') == 'VALID!'
    assert verify_card_number('5555 5555 5555 4444') == 'VALID!'
    assert verify_card_number('3056 9309 0259 04') == 'VALID!'
    assert verify_card_number('6011000990139424173') == 'VALID!'
    `)
})

verify_card_number should return INVALID! when called with an invalid credit card number.

js
({
    test: () => runPython(`
    assert verify_card_number('4539 1488 0343 6466') == 'INVALID!'
    assert verify_card_number('6011 1111 1111 1116') == 'INVALID!'
    assert verify_card_number('3782 822463 10004') == 'INVALID!'
    assert verify_card_number('5555-5555-5555-4440') == 'INVALID!'
    assert verify_card_number('3056 9309 0259 05') == 'INVALID!'
    assert verify_card_number('6011000990139424175') == 'INVALID!'
    `)
})

--seed--

--seed-contents--

py

--solutions--

py
def verify_card_number(card_number):
    card_translation = str.maketrans({'-': '', ' ': ''})
    translated_card_number = card_number.translate(card_translation)

    sum_of_odd_digits = 0
    card_number_reversed = translated_card_number[::-1]
    odd_digits = card_number_reversed[::2]

    for digit in odd_digits:
        sum_of_odd_digits += int(digit)

    sum_of_even_digits = 0
    even_digits = card_number_reversed[1::2]
    for digit in even_digits:
        number = int(digit) * 2
        if number >= 10:
            number = (number // 10) + (number % 10)
        sum_of_even_digits += number

    total = sum_of_odd_digits + sum_of_even_digits
    if total % 10 == 0:
        return 'VALID!'
    else:
        return 'INVALID!'

# Example usage
verify_card_number('4111-1111-4555-1142')