📄 cmscvn.sqc
字号:
/******************************************************* ** 源码文件名称 : cmsmkcd.SQC ** 所属子系统 : 卡管理 ** 功能描述 : 卡验证码CVN生成 ** 当前文件版本 : 0.0.0.2 ** 作 者 : Arthur.Yang ** 版本创建日期 : 2005/07/20 ** 修改记录 : ** 修改人 修改日期 修改位置*******************************************************/#define SOURCE_ASC_LEN 32#define BLOCK_ASC_LEN 16#define SOURCE_LEN 32#define BLOCK_LEN 8#define KEY_LEN 8#define CVN_LEN 3#define DEBUG_F 1#undef DEBUG_F#define INITMEM(a) memset( a, 0x00,sizeof(a) ) /**************************************************************************** ** 函数名称:cmsGenCVN ** 中文名称:卡CVN生成 ** 功能描述:按主帐户、卡失效期、服务代码和验证密钥A、验证密钥B ** 生成卡片验证码CVN(3位) ** 输入参数: ** pcSourceCode ---- 主帐户(PAN)+失效期(ED)+服务代码(SC) ** pcKeyA ---- 密钥A ** pcKeyB ---- 密钥B ** 输出参数: ** pcCvn ---- 卡验证码 ** 返回结果:int ** 0 ---- 成功 ** -1 ---- 失败****************************************************************************/EXEC SQL INCLUDE SQLCA;int cmsGenCVN( pcSourceCode, pcKeyA, pcKeyB,pcCvn )char *pcSourceCode; /* 主帐户(PAN)+失效期(ED)+服务代码(SC) */char *pcKeyA; /* 密钥A */char *pcKeyB; /* 密钥B */char *pcCvn; /* 卡验证码 */{ unsigned char acSourceAscCode[SOURCE_ASC_LEN+1]; /*源串 */ unsigned char acPackKeyA[BLOCK_LEN+1],acPackKeyB[BLOCK_LEN+1]; unsigned char acPSourceCode[SOURCE_LEN+1]; /*压缩后的源串 */ unsigned char acResultCode[3+1]; unsigned char acBlock1[BLOCK_ASC_LEN+1], acBlock2[BLOCK_ASC_LEN+1] ; unsigned char acEaBlock1[BLOCK_ASC_LEN+1],acNEaBlock1[BLOCK_ASC_LEN+1]; unsigned char acEaNEaBlock1[BLOCK_ASC_LEN+1]; unsigned char acDbEaNEaBlock1[BLOCK_ASC_LEN+1]; unsigned char acEaDbEaNEaBlock1[BLOCK_ASC_LEN+1]; unsigned char acOutTmpStr1[200] ,acOutTmpStr2[200]; int iSourceCodeLen ; /* 源串长度 */ unsigned char acBCDEaBlock1[BLOCK_LEN+1]; unsigned char acBCDBlock2[BLOCK_LEN+1]; int i =0, j =0 ,iStoreByte=0,iUsedByte=0; unsigned char c ; /* init vars */ INITMEM(acSourceAscCode) ; INITMEM(acPSourceCode) ; INITMEM(acResultCode) ; INITMEM(acBlock1) ; INITMEM(acBlock2) ; INITMEM(acEaBlock1); INITMEM(acNEaBlock1); INITMEM(acEaNEaBlock1); INITMEM(acDbEaNEaBlock1); INITMEM(acEaDbEaNEaBlock1); INITMEM(acOutTmpStr1); INITMEM(acOutTmpStr2); memset(pcCvn,0x00,CVN_LEN+1); iSourceCodeLen = strlen(pcSourceCode) ; #ifdef DEBUG_F printf("SOURCE_ASCII = [%s]\n", pcSourceCode); #endif /* cmsPackBCD将源串SourceCode压缩为128bit的串PStr, */ /* 不够128bit右补二进制0 */ cmsPackBCD( pcSourceCode, acPSourceCode,SOURCE_LEN ); /* BCD-compress keya,keyb */ cmsPackBCD( pcKeyA, acPackKeyA,BLOCK_ASC_LEN ); cmsPackBCD( pcKeyB, acPackKeyB,BLOCK_ASC_LEN ); #ifdef DEBUG_F printf("Show compressed key.....\n",acEaBlock1); printf("bcd keyA=["); for(i=0;i<BLOCK_LEN;i++) { c=(acPackKeyA[i]&0xf0)>>4; printf("%x",c); c=(acPackKeyA[i]&0x0f); printf("%x",c); } printf("]\n"); printf("bcd keyB=["); for(i=0;i<BLOCK_LEN;i++) { c=(acPackKeyB[i]&0xf0)>>4; printf("%x",c); c=(acPackKeyB[i]&0x0f); printf("%x",c); } printf("]\n"); printf(".......... \n"); #endif /* 将128bit的串分成64bit的两个数据块Block1和Block2 */ memcpy( acBlock1, acPSourceCode, BLOCK_LEN); memcpy( acBlock2, acPSourceCode+BLOCK_LEN, BLOCK_LEN); /* step 4: 调用DES加密函数encrypt(),用KeyA加密Block1为EaBlock1 */ acBlock1[BLOCK_LEN]=0x00; acBlock2[BLOCK_LEN]=0x00; /* test mid-string */ #ifdef DEBUG_F cmsUnpackBCD(acBlock1,acOutTmpStr1,BLOCK_ASC_LEN); printf("BLOCK1=[%s]\n",acOutTmpStr1 ); cmsUnpackBCD(acPackKeyA,acOutTmpStr1,BLOCK_ASC_LEN); printf("BLOCK1=[%s]\n",acOutTmpStr1 ); #endif Encrypt(acBlock1, acPackKeyA, acEaBlock1 ); /* test mid-string */ #ifdef DEBUG_F printf("acEaBlock1=[%s]\n",acEaBlock1); printf("bcd acEaBlock1=["); for(i=0;i<BLOCK_LEN;i++) { c=(acEaBlock1[i]&0xf0)>>4; printf("%x",c); c=(acEaBlock1[i]&0x0f); printf("%x",c); } printf("]\n"); printf("step 4 end ,des encrypt block1... \n"); #endif /* */ /* STEP 5: EaBlock1与Block2按位做异或运算得到nEaBlock1 */ INITMEM(acBCDEaBlock1); INITMEM(acBCDEaBlock1); INITMEM(acBCDBlock2); for( i=0;i<BLOCK_LEN;i++ ) { acNEaBlock1[i]= acEaBlock1[i]^acBlock2[i]; } acNEaBlock1[BLOCK_LEN]= 0x00 ; /* test mid-string */ #ifdef DEBUG_F cmsPackBCD( acEaBlock1, acBCDEaBlock1, BLOCK_ASC_LEN ); cmsPackBCD( acBlock2, acBCDBlock2, BLOCK_ASC_LEN ); printf("acNEaBlock1=["); for(i=0;i<BLOCK_LEN;i++) { c=(acNEaBlock1[i]&0xf0)>>4; printf("%x",c); c=(acNEaBlock1[i]&0x0f); printf("%x",c); } printf("]\n"); cmsUnpackBCD( acNEaBlock1,acOutTmpStr1,BLOCK_ASC_LEN ) ; acOutTmpStr1[BLOCK_ASC_LEN]=0; printf("acNEaBlock1=[%s],acOutTmpStr1=[%s]\n", acNEaBlock1,acOutTmpStr1); #endif /* 调用DES加密函数Encrypt(),用KeyA加密NEaBlock1为EaNEaBlock1 */ Encrypt(acNEaBlock1, acPackKeyA, acEaNEaBlock1 ); acEaNEaBlock1[BLOCK_LEN]= 0x00 ; /* test mid-string */ #ifdef DEBUG_F printf("acEaNEaBlock1=[" ); for(i=0;i<BLOCK_LEN;i++) { c=(acEaNEaBlock1[i]&0xf0)>>4; printf("%x",c); c=(acEaNEaBlock1[i]&0x0f); printf("%x",c); } printf("]\n"); #endif /* STEP 6: 调用DES解密函数decrypt(), */ /* 用KeyB解密EaNEaBlock1为DbEaNEaBlock1 */ Decrypt(acEaNEaBlock1, acPackKeyB, acDbEaNEaBlock1 ); acDbEaNEaBlock1[BLOCK_LEN]= 0x00 ; /* test mid-string */ #ifdef DEBUG_F printf("acDbEaNEaBlock1=["); for(i=0;i<BLOCK_LEN;i++) { c=(acDbEaNEaBlock1[i]&0xf0)>>4; printf("%x",c); c=(acDbEaNEaBlock1[i]&0x0f); printf("%x",c); } printf("]\n"); #endif /* STEP 7: 调用DES加密函数encrypt(), */ /* 用KeyA加密DbEanEaBlock1为EaDbEanEaBlock1 */ Encrypt(acDbEaNEaBlock1, acPackKeyA, acEaDbEaNEaBlock1 ); acEaDbEaNEaBlock1[BLOCK_LEN]= 0x00 ; /* test mid-string */ #ifdef DEBUG_F printf("acEaDbEaNEaBlock1=[" ); for(i=0;i<BLOCK_LEN;i++) { c=(acEaDbEaNEaBlock1[i]&0xf0)>>4; printf("%x",c); c=(acEaDbEaNEaBlock1[i]&0x0f); printf("%x",c); } printf("]\n"); #endif /* STEP 8: 将EaDbEanEaBlock1中的16个字符扩展到acOutTmpStr1 */ cmsUnpackBCD( acEaDbEaNEaBlock1,acOutTmpStr1,BLOCK_ASC_LEN ) ; #ifdef DEBUG_F printf("Extended RESULT=[%s]\n",acOutTmpStr1) ; #endif /* 从左向右将EaDbEanEaBlock1中的数字0-9抽出,组成一组数字串NStr */ j=0 ; for( i=0;i<BLOCK_ASC_LEN;i++) { if( acOutTmpStr1[i]>='0' && acOutTmpStr1[i]<='9' ) { acOutTmpStr2[j++]=acOutTmpStr1[i] ; } } /* 从左向右将EaDbEanEaBlock1中的字符A-F抽出,减10后余数组成一串数字*/ /* 将这串数字接在NStr后面,压缩串必须由cmsPackBCD产生,或里面>10的16 */ /* 进制数转为大写的A-F */ for( i=0;i<BLOCK_ASC_LEN;i++) { if( acOutTmpStr1[i]<'0' || acOutTmpStr1[i]>'9' ) { acOutTmpStr2[j++]=acOutTmpStr1[i]-'A'+'0' ; } } #ifdef DEBUG_F printf("Outtmp1=[%s],\n",acOutTmpStr1 ); printf("OutSring=[%s]\n",acOutTmpStr2 ); #endif memcpy( pcCvn, acOutTmpStr2, CVN_LEN ); pcCvn[CVN_LEN]=0x00; #ifdef DEBUG_F printf("cvmcvn: cvn=[%s]\n",pcCvn ); #endif return 0;}/*End of function cmsGenCVN *//******************************************************* ** 函数名称:cmsPackBCD ** 中文名称:16进制数字字符串压缩 ** 功能描述:16进制数字字符串压缩,左对齐,如果源串长度 ** 不足,右补0 。 ** ** 输入参数: ** pcSourceCode ---- 源串 ** iCnt; ---- 扩展字符数 ** ** 输出参数: ** pcResultCode ---- 结果串 ** 返回结果:int ** 0 ---- 结果串字节数 ** -1 ---- 失败*******************************************************/int cmsPackBCD( pcSourceCode, pcPackStr, iCnt )char *pcSourceCode; /* 源串 */char *pcPackStr; /* 结果串 */int iCnt; /* 扩展字符数 */{ int i=0,j=0; unsigned char c; int iSourceLen = 0; iSourceLen=strlen(pcSourceCode ); for( i=0; i<iCnt; i++) { if( i<iSourceLen) { if(pcSourceCode[i]>='0'&& pcSourceCode[i]<='9' ) { c=pcSourceCode[i]-'0'; } /*end of '0'<=[i]<='9' */ else if(pcSourceCode[i]>='a'&& pcSourceCode[i]<='f' ) { c=pcSourceCode[i]-'a'+10; } /*end of 'a'<=[i]<='f' */ else if(pcSourceCode[i]>='A'&& pcSourceCode[i]<='F') { c=pcSourceCode[i]-'A'+10; } /*end of 'A'<=[i]<='F' */ else return -1; } else c=0x00 ; if( i%2 == 0) { pcPackStr[j]=c<<4 ; } else { pcPackStr[j]=pcPackStr[j]|c ; j++; } }/* END OF FOR CYCLE */ return 0 ;} /* END OF cmsPackBCD *//******************************************************* ** 函数名称:cmsUnpackBCD ** 中文名称:16进制数字字符串扩展 ** 功能描述:16进制数字字符串扩展,10-15转为'A'-'F' ** ** 输入参数: ** pcSourceCode ---- 源串 ** pcOutStr; ---- 结果串 ** iCnt; ---- 扩展字符数 ** ** 输出参数: ** pcResultCode ---- 结果串 ** 返回结果:int ** >0 ---- 结果串字节数 ** -1 ---- 失败*******************************************************/int cmsUnpackBCD( pcSourceCode, pcOutStr, iCnt )char *pcSourceCode; /* 源串 */char *pcOutStr; /* 结果串 */int iCnt; /* 扩展字符数 */{ int i=0,j=0; unsigned c; for(i=0;i<iCnt;i++) { if(i%2 == 0) { c=pcSourceCode[j]&0xf0 ; c=c>>4; if(c>9) pcOutStr[i]='A'+c-10; else pcOutStr[i]='0'+c ; } else { c=pcSourceCode[j]&0x0f ; if(c>9) pcOutStr[i]='A'+c-10; else pcOutStr[i]='0'+c ; j++; } }/* end of for cycle */ pcOutStr[i]=0x00; return 0;} /* END OF cmsUnpackBCD */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -