CSCI 208 – Introduction to Computer Science II Fall 2013 M.Doman

advertisement
CSCI 208 – Introduction to Computer Science II
Fall 2013
M.Doman
Homework 2
Programming Problem: Luhn Checksum Validation
Due September 2, 2013
Lessons
Challenges in input processing
Converting input strings to numeric data
Problem solving
Review in C++ coding
Printed Name: ______________________________________________
Signature: _______________________________________________
You are asked to perform identification number validation. Identification numbers are used
throughout data collections. Books have ISBN numbers; databases have customer number,
vendor numbers, etc. Sometimes these numbers are entered in the computer by hand. This may
introduce potential errors by mistakenly entering wrong numbers, transposing numbers or
omitting numbers. To avoid this situation, systems have developed various techniques to
validate numbers. These techniques work by running the identification number through a
formula that generates one or more extra (hidden) digits, which become part of the original
number. If any of the digits are changed in the original part of the number, the extra digits no
longer match and the number can be rejected.
Luhn Checksum Validation
The Luhn formula is a widely used system for validating identification numbers. Using the
original number, double the value of every other digit. Then add the values of the individual
digits together. Note: if a doubled value has two digits, then the values of the individual digits
together. The identification number is valid if the sum is divisible by 10.
Write a program that takes an identification number of arbitrary length and determines whether
the number is valid under the Luhn formula.
Constraint: The program must process each character before reading the next one. In other
words, the programs will not store the characters in a data structure for later processing.
Here’s an example to help explain the problem.
Note that your program only has to validate the identification number. But to help explain, I’ll
show how the checksum number is generated.
 Computing the checksum digit
The original number is 18926. This is represented in the following illustration. Every other
digit starting from the rightmost digit will be doubled. After which all digits will be added
together. If, after doubling, a two digit result occurs, both digits are added to the sum.
1
8
9
2
2
1
+
8
+
Add digits together
1
2
6
8
+
8
1
+
2
+
1
6
Double every
other digit
2
+
2
=
24
+
6
=
30
Include check digit to
make checksum divisible
by 10

Validating the number after checksum
The number after checksum is 189266 which now includes the check digit. As before, every
second digit, starting with the digit to the left of the check digit, will be doubled. Add the
values of all digits, including the check digit, to determine if the checksum is divisible by 10.
This will indicate if the number is valid.
Break Down the Problem
PLAN
Make a list of the issues we have to tackle
 Knowing which digits to double
 Treating doubled numbers 10 and greater according to their individual digits
 Knowing when we reached the end of the number
 Reading each digit separately.
 Convert characters to digits
START WITH THE EASIEST… or the most interesting
Treating doubled numbers 10 and greater according to their individual digits
There are two possibilities for a result after doubling:
1) value is less than 10 -> No work required
2) value is 10 or greater
int digitDoubled (int digit)
{
int returnSum;
int doubleValue = digit * 2;
if (doubleValue >= 10)
{ returnSum = 1 + (doubleValue % 10);}
else
{ returnSum = doubleValue; }
return returnSum;
}
Convert characters to digits
If you use a straight cast from int=char, you get the ascii representation of the character. Ex ‘0’ =
48
There are different ways to do the conversion:
Using atoi
Note requires
#include <stdlib.h>
// Convert on character to a digit
int charToInt (char inputChar)
{
int returnInt = atoi(inputChar);
return returnInt;
}
Reading each digit separately: Knowing which digits to double
Reduce to
1) Reading one character
char charDigit;
int intDigit;
int checksum;
cout <<" \n\nEnter a 1 digit number: ";
cin >> charDigit;
intDigit = charToInt(&charDigit);
checksum = checksum + intDigit;
cout << " \n\nNumber entered: " << intDigit;
2) Reading a fixed length
Lift constraint. Figure out how to validate checksum for a string of a fix length. Use 6
Reduce problem even further… Lift doubling constraint.
checksum = 0;
cout <<" \n\nEnter a 6 digit number: ";
for (int position=1; position <=6; position++)
{ cin >> charDigit;
intDigit = charToInt(charDigit);
checksum = checksum + intDigit;
cout << " \nNumber entered: " << intDigit;
3) For fixed length .. Add doubling for every other digit starting from the second digit
from the right.
checksum = 0;
cout <<" \n\nEnter a 6 digit number: ";
for (int position=1; position <=6; position++)
{ cin >> charDigit;
intDigit = charToInt(charDigit);
if ( position % 2 ==0) {}
else {intDigit = digitDoubled(intDigit);}
checksum = checksum + intDigit;
cout << " \nNumber added: " << intDigit;
}
cout << "\nChecksum: " << checksum;
Knowing when we reached the end of the number
Experiment!!
#define EndOfInput ‘\n’
Handle both even and odd number of digits ,,, FINAL Program
// Final program
#include <iostream>
#include <cstdlib>
#define EndOfInput '\n'
using namespace std;
int charToInt (char);
int digitDoubled (int);
int main()
{
// Identify program runing
cout <<" \n\nLuhn Checksum Programs" ;
// Declare and initialize local variables
int checksumEven = 0;
int checksumOdd = 0;
int digitCount= 0;
int position = 1;
char charDigit;
int intDigit =0;
int checksum =0;
// Request input
cout <<" \nEnter the number to be verified \n";
// Read in the first character
charDigit = cin.get();
// Loop to validate the number one character at a time.
while (charDigit != EndOfInput){
digitCount++;
intDigit = charToInt(charDigit);
// Collect all data require for both an odd size or even size id number
if ( position % 2 ==0) {
// Even input position
// If the id number turns out to be an even number of digits
checksumOdd += digitDoubled(intDigit);
/ / If the id number turns out to be an odd number of digits
checksumEven += intDigit;
}
else {
// Odd input position
// If the id number turns out to be an even number of digits
checksumOdd += intDigit;
// If the id number turns out to be an odd number of digits
checksumEven += digitDoubled(intDigit);
};
charDigit = cin.get();
position++;
} // end of while loop
// set output for both even and odd digit count
if ( digitCount % 2 ==0)
{ // Even number of digits
checksum = checksumEven;}
else { // Odd number of digits
checksum = checksumOdd; }
// Validate checksum
if (checksum % 10 == 0)
{ cout << "Checksum is divisible by 10. The identification number is valid"; }
else
{ cout << "Checksum is NOT divisible by 10. The identification number is invalid"; }
cout << "\nChecksum: " << checksum;
} // End of main
////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: charToInt
//
// Convert on character to a digit
// I'll used the atoi function. It requires the value to be passed by reference
///////////////////////////////////////////////////////////////////////////////////////////////////////
int charToInt (char inputChar)
{
int returnInt = atoi(&inputChar);
return returnInt;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: digitDoubled
//
//Return value of integer doubled. If the value is greater than 10, then add the two digits.
//
// Since the doubled value is never greater than 19, I can assume that if the value is greater than
10,
// the left most digit is 1. So,I'll add 1 to the rightmost digit.
////////////////////////////////////////////////////////////////////////////////////////////////////////
int digitDoubled (int digit)
{
int returnSum;
int doubleValue = digit * 2;
if (doubleValue >= 10)
{ returnSum = 1
+ (doubleValue % 10);}
else
{ returnSum =
doubleValue; }
return returnSum;
}
Download