/*------------------------------------------------------------------ (c) 1998 Innov8 Computer Software, LLC. All rights reserved. Permission granted to freely use and distribute so long as this notice appears in tact. File Name: Luhn.p Author: Geoff Crawford Creation Date: 4/19/98 Called From: Programs Called: LuhnCheck() LuhnValue() ValidCCNo() ** LuhnValue() ** Inputs Parameters: LuhnOperand - value to calculate the check sum Outputs Parameters: Return-Value - integer, equal to the check sum Program Purpose: Calculates a Luhn Check Sum. ** ValidLuhn() ** Inputs Parameters: CheckSum - Value of the Luhn checksum Outputs Parameters: Return-Value - logical, true if the value is valid Program Purpose: Determine if the Luhn Checksum is valid. ** ValidCCNoCheck() ** Inputs Parameters: CCNo - credit card number, "-" and spaces allowed Outputs Parameters: Return-Value - logical, true if CCNo is valid Program Purpose: Determine if a Credit Card Number is valid, including whether is passes a Luhn check or not -------------------------------------------------------------------*/ FUNCTION LuhnValue RETURNS INTEGER (INPUT LuhnOperand AS CHARACTER). DEFINE VARIABLE CheckSum AS INTEGER NO-UNDO. DEFINE VARIABLE Counter AS INTEGER NO-UNDO. DEFINE VARIABLE OddDigit AS LOGICAL NO-UNDO. IF LENGTH(LuhnOperand) = 0 THEN RETURN(?). ASSIGN CheckSum = 0 OddDigit = YES. /* Each digit must be multiplied by either 1 or 2. The tricky part is that you must alternate beginning at the right most digit with 1. So use a decrementing loop to start at the LAST digit and work from right to left. */ DO Counter = LENGTH(LuhnOperand) TO 1 BY -1: /* Every odd digit is multiplied by 1, even digits by two. Instead of doing actual multiplication by 2, just lookup the correct end result in a list. This is prefered since any result greater than 10 must add the two digits of the multiplcation to achieve the final result - 2 * 5 = 10 then 1 + 0 = 1 2 * 6 = 12 then 1 + 2 = 3 2 * 7 = 14 then 1 + 4 = 5, etc. */ IF OddDigit THEN ASSIGN CheckSum = CheckSum + INTEGER(SUBSTRING(LuhnOperand,Counter,1)). ELSE ASSIGN CheckSum = CheckSum + INTEGER(ENTRY(INTEGER(SUBSTRING(LuhnOperand,Counter,1)) + 1,"0,2,4,6,8,1,3,5,7,9")). ASSIGN OddDigit = NOT OddDigit. END. /* repeat */ RETURN (CheckSum). END. /* LuhnValue Function */ /* Valid Luhns are ones divisible by 10 */ FUNCTION ValidLuhn RETURNS LOGICAL (INPUT CheckSum AS INTEGER). RETURN (CheckSum MOD 10 = 0). END. /* Validate a Credit Card Number. Includes length check and validating the Luhn. */ FUNCTION ValidCCNo RETURNS LOGICAL (INPUT CCNo AS CHARACTER). /* Put Validation Logic Here */ /* US CC#'s are 16 digits long, allow spaces and dashes */ ASSIGN CCNo = REPLACE(CCNo," ","") CCNo = REPLACE(CCNo,"-",""). IF LENGTH(CCNo) <> 16 THEN RETURN FALSE. /* Calculate the Luhn value, then verify it's a valid Luhn value. */ RETURN ValidLuhn(LuhnValue(CCNo)). END. /* LuhnCheck Function */