Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
//**************************************
//
//INCLUDE files for :CCard.h and .c
//**************************************
//
/* +++Date last modified: 05-Jul-1997 */
#ifndef CCARD_H
#define CCARD_H
enum ccard_type_ty
{
ccard_type_unknown,
ccard_type_mastercard,
ccard_type_visa,
ccard_type_amex,
ccard_type_diners,
ccard_type_discover,
ccard_type_enroute,
ccard_type_jcb,
ccard_type_bankcard
};
typedef enum ccard_type_ty ccard_type_ty;
enum ccard_error_ty
{
ccard_error_none = 0,
ccard_error_type_unknown,
ccard_error_non_numeric,
ccard_error_too_long,
ccard_error_length_incorrect,
ccard_error_checksum
};
typedef enum ccard_error_ty ccard_error_ty;
char *ccard_type_name (ccard_type_ty);
char *ccard_error_name (ccard_error_ty);
ccard_error_ty ccard_valid (char *, ccard_type_ty *);
#endif /* CCARD_H */
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
Terms of Agreement:
By using this code, you agree to the following terms...
1) You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for langauges that allow it) freely and with no charge.
2) You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this code from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.
//**************************************
//
// Name: CCard.h and .c
// Description:Credit card validation fu
// nctions.
// By: Bob Stout (republished under Open
// Content License)
//
//This code is copyrighted and has// limited warranties.Please see http://
// www.1CPlusPlusStreet.com/xq/ASP/txtCodeI
// d.441/lngWId.3/qx/vb/scripts/ShowCode.ht
// m//for details.//**************************************
//
/* +++Date last modified: 05-Jul-1997 */
/*
*ccard - credit card number validation
*1994 Peter Miller
*Public Domain
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE.
*
* MANIFEST: functions to validate credit card numbers
*
* derived from code by
*Chris Stone
*The High Mountain Software Internet Gateway
*
* translated to C by
*Peter Miller, 28-Oct-94
*This source is hereby placed in the public Domain.
*Please leave my name on it,
*and document changes in this header block.
*
* NO WARRANTY
*
*BECAUSE THE PROGRAM IS IN THE public DOMAIN, THERE IS NO
*WARRANTY for THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
*LAW. except WHEN OTHERWISE STATED IN WRITING THE AUTHORS
*AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
*WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
*BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
*AND FITNESS for A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
*THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD
*THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
*NECESSARY SERVICING, REPAIR OR CORRECTION.
*
*IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
*WRITING WILL ANY AUTHOR, OR ANY OTHER PARTY WHO MAY MODIFY
*AND/OR REDISTRIBUTE THE PROGRAM, BE LIABLE TO YOU for DAMAGES,
*INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
*DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
*(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
*RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
*OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
*PROGRAMS), EVEN if SUCH AUTHOR OR OTHER PARTY HAS BEEN ADVISED
*OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include
#include
#include "ccard.h"
#define SIZEOF(a) (sizeof(a) / sizeof((a)[0]))
#define ENDOF(a) ((a) + SIZEOF(a))
#define MINLEN 12
#define MAXLEN (MINLEN + 16)
#define L(n) (1 << ((n) - MINLEN))
static int all_numeric (char *, char *, int);
char *ccard_type_name(ccard_type_ty n)
{
static char *name[] =
{
"unknown",
"Mastercard",
"Visa",
"American Express",
"Diners Club/Carte Blanche",
"Discover",
"enRoute",
"Japanese Credit Bureau",
"Australian Bankcard",
};
if (n < 0 || n >= SIZEOF(name))
n = 0;
return name[n];
}
char *ccard_error_name(ccard_error_ty n)
{
static char *name[] =
{
"no error",
"card type unknown",
"card number contains non numeric characters",
"card number is far too long",
"card number is the wrong length",
"checksum incorrect",
};
if (n < 0 || n >= SIZEOF(name))
return "unknown";
return name[n];
}
static int verify_checksum(char *credit_card)
{
char*cp;
int dbl;
int check_sum;
/*
* this checksum algorithm has a name,
* but I can't think of it.
*/
check_sum = 0;
dbl = 0;
/* assert(credit_card[0]); */
cp = credit_card + strlen(credit_card) - 1;
while (cp >= credit_card)
{
int c;
c = *cp-- - '0';
if (dbl)
{
c *= 2;
if (c >= 10)
c -= 9;
}
check_sum += c;
dbl = !dbl;
}
return ((check_sum % 10) == 0);
}
static int all_numeric(char *s1, char *s2, int max)
{
while (*s1)
{
if (isspace(*s1) || *s1 == '-')
{
++s1;
continue;
}
if (!isdigit(*s1))
return ccard_error_non_numeric;
if (max <= 0)
return ccard_error_too_long;
*s2++ = *s1++;
--max;
}
*s2 = 0;
return ccard_error_none;
}
ccard_error_ty ccard_valid(char *credit_card_in, ccard_type_ty *card_type)
{
typedef struct table_ty table_ty;
struct table_ty
{
char*prefix;
int length_mask;
ccard_type_ty type;
int checksum;
};
static table_ty table[] =
{
{ "1800", L(15), ccard_type_jcb, 1, },
{ "2014", L(15), ccard_type_enroute, 0, },
{ "2131", L(15), ccard_type_jcb, 1, },
{ "2149", L(15), ccard_type_enroute, 0, },
{ "300", L(14), ccard_type_diners, 1, },
{ "301", L(14), ccard_type_diners, 1, },
{ "302", L(14), ccard_type_diners, 1, },
{ "303", L(14), ccard_type_diners, 1, },
{ "304", L(14), ccard_type_diners, 1, },
{ "305", L(14), ccard_type_diners, 1, },
{ "34",L(15), ccard_type_amex, 1, },
{ "36",L(14), ccard_type_diners, 1, },
{ "37",L(15), ccard_type_amex, 1, },
{ "38",L(14), ccard_type_diners, 1, },
{ "3",L(16), ccard_type_jcb, 1, },
{ "4",L(13)|L(16), ccard_type_visa, 1, },
{ "51",L(16), ccard_type_mastercard, 1, },
{ "52",L(16), ccard_type_mastercard, 1, },
{ "53",L(16), ccard_type_mastercard, 1, },
{ "54",L(16), ccard_type_mastercard, 1, },
{ "55",L(16), ccard_type_mastercard, 1, },
{ "56",L(16), ccard_type_bankcard, 1, },
{ "6011", L(16), ccard_type_discover, 1, },
};
table_ty*tp;
charcredit_card[MAXLEN + 1];
ccard_error_tyerr;
int len;
/*
* copy the number, eliding spaces
* defer any errors until after we have tried to guess the card type
*/
err = all_numeric(credit_card_in, credit_card, MAXLEN);
/*
* look for the card prefix in the table
* to determine the card type
*/
for (tp = table; tp < ENDOF(table); ++tp)
{
if (!memcmp(tp->prefix, credit_card, strlen(tp->prefix)))
break;
}
if (tp >= ENDOF(table))
{
*card_type = ccard_type_unknown;
return ccard_error_type_unknown;
}
*card_type = tp->type;
if (err != ccard_error_none)
return err;
/*
* set the card type, then check the length
*/
/* assert(tp->correct_length <= MAXLEN); */
len = strlen(credit_card);
if (len < MINLEN || (L(len) & tp->length_mask) == 0)
return ccard_error_length_incorrect;
/*
* checksum
*/
if (tp->checksum && !verify_checksum(credit_card))
return ccard_error_checksum;
/*
* no errors found
*/
return ccard_error_none;
}
#ifdef TEST
/*
*ccard - credit card number validation
*1994 Peter Miller
*Public Domain
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE.
*
* MANIFEST: program entry point
*/
#include
#include
#include
#include "ccardplv.h"
static char *progname;
static int suffix(char *s1, char *s2)
{
int len1 = strlen(s1);
int len2 = strlen(s2);
return (len2 < len1 && !memcmp(s1 + len1 - len2, s2, len2));
}
static void print_version(char *s)
{
char*ep;
for (;;)
{
ep = strrchr(s, '/');
if (!ep)
break;
if (ep > s && !ep[1])
{
*ep = 0;
continue;
}
s = ep + 1;
break;
}
progname = s;
fprintf(stderr, "%s version %s\n", progname, PATCHLEVEL);
}
int main(int argc, char *argv[])
{
int j;
print_version(argv[0]);
for (j = 1; j < argc; ++j)
{
ccard_type_ty type;
ccard_error_tyerr;
char*s;
err = ccard_valid(argv[j], &type);
if (err)
{
if (type != ccard_type_unknown)
{
fprintf
(
stderr,
"%s: %s: %s (%s)\n",
progname,
argv[j],
ccard_error_name(err),
ccard_type_name(type)
);
}
else
{
fprintf
(
stderr,
"%s: %s: %s\n",
progname,
argv[j],
ccard_error_name(err)
);
}
exit(1);
}
printf("\"%s\" is a", argv[j]);
s = ccard_type_name(type);
if (strchr("AEIOUaeiou", s[0]))
printf("n");
printf(" %s", s);
if (!suffix(s, "card"))
printf(" card");
printf("\n");
}
exit(0);
return 0;
}
#endif /* TEST */
Other 156 submission(s) by this author