根据《中国银联2.0》标准 - Q/CUP 002-2004 提供的算法
Luhn计算模10“隔位2倍加”校验数的公式
计算步骤如下:
步骤1:从右边第1个数字(低序)开始每隔一位乘以 2 。
步骤2:把在步骤1中获得的乘积的各位数字与原号码中未乘2的各位数字相加。
步骤3:从邻近的较高的一个以0结尾的数中减去步骤2中所得到的总和
[这相当于求这个总和的低位数字(个位数)的“ 10的补数 ”],
如果在步骤2得到的总和是以零结尾的数(如30、40等等),则校验数字就是零。
[例]:
无校验数的卡号655002 0001 00000328 步骤
6 5 5 0 0 2 0 0 0 1 0 0 0 0 0 3 2 8 1
x2 x2 x2 x2 x2 x2 x2 x2 x2
10 0 4 0 2 0 0 6 16
6 + 1 + 0 + 5 + 0 + 0 + 4 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 0 + 6 + 2 + 1 + 6 = 33 2
40 – 33 = 7 3
即校验为 7
带有校验数的卡号为:655002 0001 00000328 7
(银联要求的卡号是13-19位,此程序暂时满足19位卡号的计算,19位以下的有待修改)
功能:检查19位的银行卡号码的有效性
运行环境:Red Hat Enterprise Linux AS release 3 、AIX Version 5 操作系统上测试通过
编译命令:cc -o card card.c
执行命令:./card
源代码:
/************************************************************
FileName: card.c
Author: yuanfen127
Date: 2005年12月01日
Description: 银行卡号码的有效性检查程序
Version: 1.0
Function List:
1. int CreatBit(char *cdno, int length) 根据前面length-1位长度生成最后校验位
2. int iCheckBit(char *sbuf) 调用CreateBit生成校验位和输入的比较 History:
***********************************************************/
#include
#include
main()
{
char card_no[20];
printf("请输入19位卡号:");
scanf("%19s",card_no);
printf("卡号:%s\n",card_no);
/*CreatBit(card_no,strlen(card_no)-1);*/
if ( strlen(card_no)
{
printf("卡号长度错误\n");
return -1;
}
if ( 0 != iCheckBit(card_no) )
{
printf("卡号错误!\n");
}
else
{
printf("卡号正确!\n");
}
}
int CreatBit(char *cdno, int length)
{
int CI[18]={1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2};
int i,d,result;
int chk_dig=0;
if ( strlen(cdno)
{
printf("输入的长度错,长度=%d\n",strlen(cdno));
return -1;
}
for ( i=0; i
{
d = cdno[i]-48;
result = d * CI[i];
chk_dig += result/10 + result%10;
}
chk_dig = 10 - chk_dig%10;
chk_dig = (chk_dig==10) ? 0 : chk_dig;
cdno[length] = chk_dig + 48;
printf("检验位:%d\n",chk_dig);
return 0;
}
int iCheckBit(char *sbuf)
{
char cardbuf[19];
int l_len;
memcpy( cardbuf, sbuf, 19 );
l_len = strlen(sbuf);
l_len = l_len > 19 ? 19 : l_len ;
if( (CreatBit(cardbuf, l_len - 1 ) != 0) || memcmp(sbuf, cardbuf, l_len)) {
return(-1);
}
return(0);
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yuanfen127/archive/2005/12/24/560716.aspx
根据《中国银联2.0》标准 - Q/CUP 002-2004 提供的算法
Luhn计算模10“隔位2倍加”校验数的公式
计算步骤如下:
步骤1:从右边第1个数字(低序)开始每隔一位乘以 2 。
步骤2:把在步骤1中获得的乘积的各位数字与原号码中未乘2的各位数字相加。
步骤3:从邻近的较高的一个以0结尾的数中减去步骤2中所得到的总和
[这相当于求这个总和的低位数字(个位数)的“ 10的补数 ”],
如果在步骤2得到的总和是以零结尾的数(如30、40等等),则校验数字就是零。
[例]:
无校验数的卡号655002 0001 00000328 步骤
6 5 5 0 0 2 0 0 0 1 0 0 0 0 0 3 2 8 1
x2 x2 x2 x2 x2 x2 x2 x2 x2
10 0 4 0 2 0 0 6 16
6 + 1 + 0 + 5 + 0 + 0 + 4 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 0 + 6 + 2 + 1 + 6 = 33 2
40 – 33 = 7 3
即校验为 7
带有校验数的卡号为:655002 0001 00000328 7
(银联要求的卡号是13-19位,此程序暂时满足19位卡号的计算,19位以下的有待修改)
功能:检查19位的银行卡号码的有效性
运行环境:Red Hat Enterprise Linux AS release 3 、AIX Version 5 操作系统上测试通过
编译命令:cc -o card card.c
执行命令:./card
源代码:
/************************************************************
FileName: card.c
Author: yuanfen127
Date: 2005年12月01日
Description: 银行卡号码的有效性检查程序
Version: 1.0
Function List:
1. int CreatBit(char *cdno, int length) 根据前面length-1位长度生成最后校验位
2. int iCheckBit(char *sbuf) 调用CreateBit生成校验位和输入的比较 History:
***********************************************************/
#include
#include
main()
{
char card_no[20];
printf("请输入19位卡号:");
scanf("%19s",card_no);
printf("卡号:%s\n",card_no);
/*CreatBit(card_no,strlen(card_no)-1);*/
if ( strlen(card_no)
{
printf("卡号长度错误\n");
return -1;
}
if ( 0 != iCheckBit(card_no) )
{
printf("卡号错误!\n");
}
else
{
printf("卡号正确!\n");
}
}
int CreatBit(char *cdno, int length)
{
int CI[18]={1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2};
int i,d,result;
int chk_dig=0;
if ( strlen(cdno)
{
printf("输入的长度错,长度=%d\n",strlen(cdno));
return -1;
}
for ( i=0; i
{
d = cdno[i]-48;
result = d * CI[i];
chk_dig += result/10 + result%10;
}
chk_dig = 10 - chk_dig%10;
chk_dig = (chk_dig==10) ? 0 : chk_dig;
cdno[length] = chk_dig + 48;
printf("检验位:%d\n",chk_dig);
return 0;
}
int iCheckBit(char *sbuf)
{
char cardbuf[19];
int l_len;
memcpy( cardbuf, sbuf, 19 );
l_len = strlen(sbuf);
l_len = l_len > 19 ? 19 : l_len ;
if( (CreatBit(cardbuf, l_len - 1 ) != 0) || memcmp(sbuf, cardbuf, l_len)) {
return(-1);
}
return(0);
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yuanfen127/archive/2005/12/24/560716.aspx