[Finally, OS/2 users and Windows users will agree on something (click here)]

[Previous]
the REXX Files- by Dr. Dirk Terrell
 [Next]

I stumbled across something this month that might be of interest to you, especially if you use REXX to write CGI programs for secure online credit card transactions. Credit card numbers are notoriously easy to mistype, so it would be nice to be able to check a number that someone has entered to see if it is a valid number.

Many account numbers, like those for Visa and MasterCard, employ a type of checksum to make sure that the number is valid. This is accomplished by the use of a "check digit" appended to the number. The digits of the number are then run through a "check equation" to see if the result is 0.

There are all sorts of check equations. The check equation for Visa and MasterCard numbers works like this:

  1. Label the digits of the account number from left to right starting with 1.
  2. For the digits with odd-number labels, compute the sum of the digits that result when you multiply the digit in question by 2. For example, if the third digit in the account number is 7, you would get 2*7=14, and then add 1+4 to get 5.
  3. For the digits with even-numbered labels, just take the value of the digit.
  4. Sum all of the digits resulting from steps (2) and (3). If the result is evenly divisible by 10, then it is valid ("modulo 10" in mathematics lingo).

The text-handling functions of REXX make it very easy to implement this algorithm. First we read in the account number and initialize a variable to compute the sum in step (4) above:

/* Check a Visa or MC credit card number for accuracy */
Parse Arg CCNumber
Sum=0
Now set up a loop that will run over all of the digits of the account number. The LENGTH() returns the number of characters in a string, so that is what we want to use:
Do i=1 to Length(CCNumber)
Now comes the meat of the program. We need to perform the calculations in steps (2) and (3) above. First we need to know whether we are working on one of the odd-labeled digits or one of the even ones. An If... Then... Else block would work nicely for this. Since we are using the variable i to loop over the digits of the account number, all we need to do is check to see if it is even or odd. To accomplish this we use the // operator which divides two numbers and returns the remainder. If we divide i by 2 and check for the remainder, it will be 0 if i is even and 1 if it is odd. So, we set up our block like this:
   if i//2=0 then Do /* i is even, execute step (3) */
      ...
      end /* do */
   else Do /* i is odd, execute step (2) */
      ...   
   end /* do */
Now, step 3 is pretty simple to code. All we do is add the value of the digit to our variable Sum. Since i tells us which digit we are working on, we can use the SubStr function to retrieve the digit in question:
Sum=Sum+SubStr(CCNumber,i,1)
The third parameter in the function call is the length of the substring that we want. Since we only want one digit, it is set to 1.

Coding step (2) is, as you might guess, a little bit more involved. First we extract the current digit with SubStr as before, and then multiply it by 2:

Product=2*SubStr(CCNumber,i,1)
Now we need to initialize another variable for summing the digits of variable Product:
DigitSum=0
Next we loop over the digits of Product (which will number either one or two), and sum them:
Do j=1 to Length(Product)
   DigitSum=DigitSum+SubStr(Product,j,1)
end /* do */
Finally, we add the result to our main summation variable, Sum:
Sum=Sum+DigitSum
The last step is to see if the checksum we computed is divisible by 10, again using the // operator:
If Sum//10=0 then 
   Say CCNumber "is valid."
else
   Say CCNumber "is invalid. ("||Sum||")"
So, the final program looks like this:
/* Check a Visa or MC credit card number for accuracy */
Parse Arg CCNumber
Sum=0
Do i=1 to Length(CCNumber)
   if i//2=0 then Do
      Sum=Sum+SubStr(CCNumber,i,1)
      end /* do */
   else Do
      Product=2*SubStr(CCNumber,i,1)
      DigitSum=0
      Do j=1 to Length(Product)
         DigitSum=DigitSum+SubStr(Product,j,1)
      end /* do */
      Sum=Sum+DigitSum
   end /* do */
end /* do */
If Sum//10=0 then 
   Say CCNumber "is valid."
else
   Say CCNumber "is invalid. ("||Sum||")"
Exit
Other numbers that employ checksums of this sort are the ISBN numbers for books, and processing codes on checks drawn on US banks. The latter is computed by this algorithm:
3*d1 + 7*d2 + d3 + 3*d4 + 7*d5 + d6 + 3*d7 + 7*d8 + d9 = 0 (modulo 10)
where d1, d2, etc. represent digit 1, digit 2, and so on. Code that one up and test it out on the processing code on your checks (the 9-digit code in the lower left).

Let me close this month with a request for ideas that you would like to see covered in this column. If you have something you'd like to see explained or coded, drop me a line at admin@os2ss.com. I'd like to see this column be a little more interactive than it is now. If you have questions, suggestions, or even code that you've written that you think could be useful to illustrate the capabilities of REXX to those trying to learn it, please send them my way!

* * *

Dr. Dirk Terrell is an astronomer at the University of Florida specializing in interacting binary stars. His hobbies include cave diving, martial arts, painting and writing OS/2 software such as HTML Wizard.


[Previous]
 [Index]
 [Feedback]
 [Next]

[Our Sponsor: Keller Group Inc. - Developers of FaxWorks for OS/2 and PMfax.]

Copyright © 1998 - Falcon Networking ISSN 1203-5696