This unit is based on the public domain program ccard by Peter Miller.
It is released to the public for free of charge use, but the author
reserves all rights.

copyright 1996 by Shawn Wilson Harvell ( shawn@inet.net )

usage:

Add this unit to the uses clause of any unit that needs access to the
validation function.

IsValidCreditCardNumber( CardNumber, ReturnMessage ) returns Boolean

for example, use it in an if statement that Messages user if invalid.

CardNumber is a string containing the number that you want to validate
ReturnMessage is a string where the function can place any messages it
may return ( meaning that it will overwrite whatever is in it )

returns true if valid, false otherwise.

dashes and space in the input value are taken care of by the function,
if other characters are possible, you may wish to remove them as well.
The function RemoveChar will take care of this quite easily, simply
pass the input string and the char you wish to delete.

Users are free to modify this unit for their own use, but in
distributing you should advise all users of the changes made.

Use this unit at your own risk, it does not come with any warranties
either express or implied. Damages resulting from the use of this
unit are the sole responsibility of the user.

This should work as is for Delphi versions 1 and 2, some slight
modifications may be necessary for Turbo Pascal ( mainly due to use to
conversion functions from the SysUtils unit ).

If you do find this useful, have any comments or suggestions, please
drop the author an email at shawn@inet.net

Revision History

version 1.1 -- December 20, 1996
blooper with Discover cards, added their length mask to the "database"

{**************************************************************************
This is probably the most confusing part of the code you will see, I know
that it is some of the most confusing I have ever seen. Basically, this
function is extracting each digit of the number and subjecting it to the
checksum formula established by the credit card companies. It works from
the end to the front.
**************************************************************************}

while (Counter >= 1) do
begin
{ get the current digit }
PartNumber := Copy(CardNumber, Counter, 1);
Number := StrToInt(PartNumber); { convert to integer }
if (Flag) then { only do every other digit }
begin
Number := Number * 2;
if (Number >= 10) then
Number := Number - 9;
end;
CheckSum := CheckSum + Number;

if (CardName = 'MasterCard') then
result := ShiftMask(16);
if (CardName = 'Visa') then
result := (ShiftMask(13) or ShiftMask(16));
if (CardName = 'American Express') then
result := ShiftMask(15);
if (CardName = 'Diner Club/Carte Blanche') then
result := ShiftMask(14);
if (CardName = 'Discover') then
result := ShiftMask(16);

end;

function IsValidCreditCardNumber(CardNumber: string; var MessageText: string):
Boolean;
var
StrippedNumber: string; { used to hold the number bereft of extra chars }
Index: Integer; { general purpose counter for loops, etc }
TheMask: Integer; { number we will use for the mask }
FoundIt: Boolean; { used to indicate when something is found }
CardName: string; { stores the name of the type of card }
PerformChecksum: Boolean; { the enRoute type of card doesn't get it }
begin