Link to home
Start Free TrialLog in
Avatar of milance
milance

asked on

Testing Credit Card Number

I want to make a procedure for testing a Credit Card number (VISA card), but I don't knew how to do this. Can
you help me, please?
Avatar of ecw
ecw

I used to do this sort of stuff many years ago when I was an EPOS programmer.  It's a very simple checkdigit algorithm which I have forgotten - there isn't much call for it day to day.  However a quick search on Alta Vista found this:

URL: http://www.plato-net.or.jp/usr/vladimir/ugtxt/txt/creditalgorith.html

This algorithm is used for credit and charge cards.  Store loyalty cards often depend on obscene account number length eg. 24+ digits.

Here is a simple bit of code to check a card number based on the content of the above page.  It returns non-zero if the card no. is ok, and puts the calculated check digit in *check_digit.

Ed.

--CUT HERE--
#include <string.h>

int     check_card(char *card, int *check_digit)
{
char    *c;
char    *last = card + strlen(card + 1);
int     dval;
int     cval;
int     cpos;

        for (c = card, cpos = 1, cval = 0; c < last; ++c, ++cpos) {
                if ((dval = (*c - '0') * (1 + (cpos & 1))) > 9) {
                        dval = dval - 9;
                }
                cval += dval;
        }
        return (*check_digit = 10 - (cval % 10)) == (*last - '0');
}

int     main(argc, argv)
int     argc;
char    *argv[];
{
int     cd;
        while (--argc) {
                ++argv;
                if (check_card(*argv, &cd)) {
                        printf("Check succeeded (%s)\n", *argv);
                } else {
                        printf("Check failed (%s) - should be %-d\n", *argv,cd);
                }
        }
        return 0;
}


Bugger, this is the pascal group, and I've just chucked in some 'C'.  Believe it or not, most of the EPOS work (I alluded to above) was in Pascal, so here goes...
Description is basically same as 'C' version, but it needs extra parameter clen - the length of the card number.
  Ed.

function check_card(card : packed array [1..32] of char; clen : integer; var cd : integer) : boolean
var
  c        : integer;
  cpos   : integer;
  dval    : integer;
  cval    : integer;
begin
 cpos := 1; dval := 0; cval := 0;
 while (cpos < clen)
   begin
    dval := ord(card[cpos]) * (1 + (cpos mod 2));
    if (dval > 9) dval := dval - 9;
    cval := cval + dval;
   end;
  cd := 10 - (cval mod 10);
  check_card := cd = ord(card[clen])
end;
Again, my pascal is very rusty.  So here's something that compiles at least.

function check_card(card : array of char; clen : integer; var cd : integer) : boolean;
        var
          c        : integer;
          cpos   : integer;
          dval    : integer;
          cval    : integer;
        begin
         cpos := 1; dval := 0; cval := 0;
         while (cpos < clen) do
           begin
            dval := ord(card[cpos]) * (1 + (cpos mod 2));
            if (dval > 9) then dval := dval - 9;
            cval := cval + dval;
           end;
          cd := 10 - (cval mod 10);
          check_card := cd = ord(card[clen])
        end;
hm, i didnt test it, but i think you can't give an ARRAY as Argument to a Function. Try to create first a TYPE and then give a such VAR to the Function. Maybe this helps...

TYPE
  CardData : Array [0..32] of Char (would be String[32] anyway)

VAR
  Card : CardData;

perhaps you used null-terminated strings from C, what in Pascal would be pChar.
ASKER CERTIFIED SOLUTION
Avatar of mmilan
mmilan

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ozo
For MasterCard, the first digit should be 5
For Visa, it should be 4,
For Discover card, 6
For American Express, the first two digits, should be 3 7
And this is from me and from the book VBScript4dummies.
It's html but it works and the code is easy enough to convert to pascal, or isn't it?

//--------------- Code starts -------------------------------------------------------------------
Sub CheckCard_OnClick()
        Select case CardType(CardNum.Value)
                Case "BLANK"
                        Msg = "Diese Zahl ist keine Kreditkartennummer"
                        Icon=16
                Case "NONNUMBER"
                        Msg = "Diese Zahl enthält mindestens ein nicht-numerisches Zeichen"
                        Icon=16
                Case "AMEX"
                        Msg ="Dies ist eine gültige American Express-Kartennummer"
                        Icon=64
                Case "VISA"
                        Msg ="Dies ist eine gültige Visa-Kartennummer"          
                        Icon=64
                Case "MASTER"
                        Msg ="Dies ist eine gültige MasterCard-Kartennummer"            
                        Icon=64
                Case "DISCOVER"
                        Msg = "Dies ist eine gültige Discover-Kartennummer"
                        Icon=64
                Case "INVALID"
                        Msg = "Diese Kreditkartennummer ist UNGÜLTIG"
                        Icon=16
        End Select
        Msg = CardNum.Value & chr(13) & chr(13) & Msg
        Msgbox Msg, Icon, "Überprüfung der Kreditkartennummer"
End Sub

''''''''''''''''''
Sub ClearFields_OnClick()
        CardNum.Value=""
End Sub

''''''''''''''''
Function CardType(N)
    Dim i, CheckSum, Prod
    MASK = "2121212121212121"
    Num=N

        if Num="" then
            CardType="LEER"
                exit function
        end if

'   Remove spaces
        NumDigits=Len(Num)
        TempNum=""
        for i=1 to NumDigits
                Digit=mid(Num,i,1)
                if Digit <> " " Then TempNum=TempNum & Digit
        next

'       Remove dashes
        TempNum2=""
        for i=1 to Len(TempNum)
                Digit=mid(TempNum,i,1)
                if Digit <> "-" Then TempNum2=TempNum2 & Digit
        next

'       Check for non-numbers
        for i=1 to len(TempNum2)
                if not isnumeric(mid(TempNum2,i,1)) then
                        CardType="BLANK"
                        exit function
                end if
        next
        Num=TempNum2

'   Determine card type
    If Left(Num, 2) = "37" Then CardType = "AMEX"
    If Left(Num, 1) = "4" Then CardType = "VISA"
    If Left(Num, 1) = "5" Then CardType = "MASTER"
    If Left(Num, 1) = "6" Then CardType = "DISCOVER"
   
'   Make card length = 16
    Select Case Len(Num)
        Case 13: Num = "000" & Num
        Case 14: Num = "00" & Num
        Case 15: Num = "0" & Num
        Case 16: Num = Num
        Case Else
            CardType="UNGÜLTIG"
            Exit Function
    End Select
   
'   Calculate check sum
    CheckSum = 0
    For i = 1 To 16
        Prod = Mid(Num, i, 1) * Mid(MASK, i, 1)
        If Prod > 9 Then Prod = Prod - 9
        CheckSum = CheckSum + Prod
    Next
    CheckSum = CheckSum Mod 10
   
'   Invalid card
    If CheckSum <> 0 Then
       CardType="UNGÜLTIG"
       Exit Function
    End If
End Function

//------------------- Code ends -----------------------------------------------------------

;-)

That might be ok if you don't accept Diner's Club, which would start with 3, and have a second digit other than 7...
jjkhkjhjhj
Avatar of milance

ASKER

How can I test expiriens date?
You cannot