CS303E Homework 4

Instructor: Dr. Bill Young
Due Date: Monday, September 21 2026 at 11:59pm

Copyright © William D. Young. All rights reserved.

Assignment: Luhn's Algorithm

The Luhn algorithm or Luhn formula was created by IBM scientist Hans Peter Luhn. It is a simple check digit formula used to validate a variety of identification numbers, such as credit card numbers. The scheme allows a computer to quickly check for errors when a human is entering the number. Many credit card numbers and many government identification numbers use the algorithm as a simple method of distinguishing valid numbers from mistyped or otherwise incorrect numbers.

It works as follows: One digit (usually the least significant or rightmost digit) in the number is treated as the check digit. The other digits, called the payload are used to re-compute the check digit using a simple arithmetic computation. The computed value is then compared to the check digit. If the two match, it is assumed that the number is correct. If some digit was mis-typed or two digits were transposed, the check will probably fail. The algorithm was designed to protect against accidental errors, not malicious attacks, as it's not hard to defeat.

Here are the steps of the algorithm:

  1. Start with the number to check: dn...d2d1d0.
  2. Remove and save the check digit d0 from the number. This leaves the payload: dn...d2d1
  3. Double every digit with an odd number subscript. If a doubled digit exceeds 9, subtract 9 from the result. For example, if the digit is 6, double it to get 12, and then subtract 9 to get 3 as the result for that digit.
  4. Sum all of the resulting digits (including those that were doubled). Call this s.
  5. The check digit is calculated as (( 10 - ( s mod 10 ) ) mod 10). Recall that mod is the "%" operator.
  6. Compare the computed check digit with the stored check digit d0. If they match, accept the number as correct. Otherwise, reject the number.

Note: In the picture at the top, they've reversed the order of the digits.

Your Assignment:

For this assignment, you'll implement a simplified version of the Luhn Algorithm. Your version need only deal with 7-digit numbers, where the least significant (rightmost) digit is assumed to be the stored check digit. (To do Luhn in generality for arbitrary sized number, you'd need loops, which we haven't covered yet.) Perform the following steps:
  1. Using an input() statement, accept from the user an integer n.
  2. Validate that n is non-negative and less than 107. If not, print an error message and stop.
  3. Extract the digits and print them as you go; see the samples below. Do this arithmetically; don't convert the number to a string. Print each digit and the rest of the number after that digit is removed.
  4. Compute the expected check value from the payload: d6...d2d1.
  5. Compare it to the stored check digit d0.
  6. If they agree, print a message saying so. (See the samples below.)
  7. If they disagree, print a message saying so, and what the digit should be (the check value you computed).
Note that n can have fewer than 7 digits; if so, assume that it's padded on the left with 0's. Your code shouldn't have to check that.

Extracting the Digits

How do you go about extracting the 7 digits from n? Recall that if you have a number n, then n % 10 is the remainder when you divide by 10. For a decimal number, that's just the least significant digit. Also, n // 10 is what remains after you drop the least significant digit. E.g., to get digits d0 and d1 from a k-digit number n, you could do the following:
    d0 = n % 10                             # extract d0
    r = n // 10                             # digits [k-1..1]

    d1 = r % 10                             # digit d1
    r = r // 10                             # digits [k-1..2]
To extract the other digits, just continue in the same way. Note: we could do this in a loop to extract all of the digits into a list, but we haven't yet covered loops or lists. So don't do that, even if you know how.

Sample Output

> python Luhn.py
Enter a non-negative 7-digit integer: 87654321
Illegal number entered.
> python Luhn.py
Enter a non-negative 7-digit integer: -1234567
Illegal number entered.
> python Luhn.py
Enter a non-negative 7-digit integer: 7654321
d0:1; r:765432
d1:2; r:76543
d2:3; r:7654
d3:4; r:765
d4:5; r:76
d5:6; r:7
d6:7; r:0
Number is invalid:  7654321
Check digit should be:  0
> python Luhn.py
Enter a non-negative 7-digit integer: 7654320
d0:0; r:765432
d1:2; r:76543
d2:3; r:7654
d3:4; r:765
d4:5; r:76
d5:6; r:7
d6:7; r:0
Number is valid:  7654320
> python Luhn.py
Enter a non-negative 7-digit integer: 4321
d0:1; r:432
d1:2; r:43
d2:3; r:4
d3:4; r:0
d4:0; r:0
d5:0; r:0
d6:0; r:0
Number is invalid:  4321
Check digit should be:  5
> python Luhn.py
Enter a non-negative 7-digit integer: 4325
d0:5; r:432
d1:2; r:43
d2:3; r:4
d3:4; r:0
d4:0; r:0
d5:0; r:0
d6:0; r:0
Number is valid:  4325
> 

Turning in the Assignment:

The program should be in a file named Luhn.py. Submit the file via Canvas before the deadline shown at the top of this page. Submit it to the assignment hw4 under the assignments sections by uploading your Python file.

Be sure to test your program before submission. It must also contain a header with the following format:

# Assignment: HW4
# File: Luhn.py
# Student: 
# UT EID:
# Course Name: CS303E
# 
# Date:
# Description of Program: 

If you submit multiple times to Canvas, it will rename your file name to something like Luhn-1.py, Luhn-2.py, etc. Don't worry about that; we'll grade the latest version.

Programming tips

You can assume. When an assignment says that "you can assume" something about the input, that just means that you don't have to check it. If the user enters an input that doesn't meet that assumption, the program can crash or behave badly. That's not your problem.

For many of the assignments this semester, we'll say that you can assume certain things about the inputs, often because you don't yet have the skills necessary to check for certain errors. But if you get a programming job, you should always validate the inputs as much as possible. In general, it's bad programming practice to allow bad inputs to crash your program; it means that your program is not robust. Later we'll insist that you "validate" some inputs, meaning to assure that they do meet specifications.