/* ===========================================================>>
* 文件名:iso8583_gm.c
* 作 者:王伟
* 日 期:2012/04
* 程序的作用:按照中国银联POS终端规范解析8583报文
*/
#include "iso8583_gm.h"
struct ISO8583 master[128] = {
/* FIELD 1 */ {0,"BIT MAP,EXTENDED ", 16, 0, 0, 0, NULL},
/* FIELD 2 */ {0,"PRIMARY ACCOUNT NUMBER ", 19, 0, 2, 0, NULL},
/* FIELD 3 */ {0,"PROCESSING CODE ", 6, 0, 0, 0, NULL},
/* FIELD 4 */ {0,"AMOUNT, TRANSACTION ", 12, 0, 0, 0, NULL},
/* FIELD 5 */ {0,"AMOUNT, SETTLEMENT ", 12, 0, 0, 0, NULL},
/* FIELD 6 */ {0,"AMOUNT, CARDHOLDER BILLING ", 12, 0, 0, 0, NULL},
/* FIELD 7 */ {0,"TRANSACTION DATE AND TIME ", 10, 0, 0, 0, NULL},
/* FIELD 8 */ {0,"AMOUNT, CARDHOLDER BILLING FEE ", 8, 0, 0, 0, NULL},
/* FIELD 9 */ {0,"CONVERSION RATE,SETTLEMENT ", 8, 0, 0, 0, NULL},
/* FIELD 10 */ {0,"CONVERSION RATE,CARDHOLDER BILLING ", 8, 0, 0, 0, NULL},
/* FIELD 11 */ {0,"SYSTEM TRACE AUDIT NUMBER ", 6, 0, 0, 0, NULL},
/* FIELD 12 */ {0,"TIME, LOCAL TRANSACTION ", 6, 0, 0, 0, NULL},
/* FIELD 13 */ {0,"DATE, LOCAL TRANSACTION ", 4, 0, 0, 0, NULL},
/* FIELD 14 */ {0,"DATE, EXPIRATION ", 4, 0, 0, 0, NULL},
/* FIELD 15 */ {0,"DATE, SETTLEMENT ", 4, 0, 0, 0, NULL},
/* FIELD 16 */ {0,"DATE, CONVERSION ", 4, 0, 0, 0, NULL},
/* FIELD 17 */ {0,"DATE, CAPTURE ", 4, 0, 0, 0, NULL},
/* FIELD 18 */ {0,"MERCHANT'S TYPE ", 4, 0, 0, 0, NULL},
/* FIELD 19 */ {0,"ACQUIRING INSTITUTION COUNTRY CODE ", 3, 0, 0, 0, NULL},
/* FIELD 20 */ {0,"PRIM. ACCNT. NO. EXT.,COUNTRY CODE ", 3, 0, 0, 0, NULL},
/* FIELD 21 */ {0,"FORWARDING INSTITUTION COUNTRY CODE ", 3, 0, 0, 0, NULL},
/* FIELD 22 */ {0,"POINT OF SERVICE ENTRY MODE ", 3, 0, 0, 0, NULL},
/* FIELD 23 */ {0,"CARD SEQUENCE NUMBER ", 3, 0, 0, 0, NULL},
/* FIELD 24 */ {0,"NETWORK INTERNATIONAL IDENTIFIER ", 3, 0, 0, 0, NULL},
/* FIELD 25 */ {0,"POINT OF SERVICE CONDITION CODE ", 2, 0, 0, 0, NULL},
/* FIELD 26 */ {0,"POINT OF SERVICE PIN CAPTURE CODE ", 2, 0, 0, 0, NULL},
/* FIELD 27 */ {0,"AUTH IDENTIFICATION RESPONSE LENGTH ", 1, 0, 0, 0, NULL},
/* FIELD 28 */ {0,"AMOUNT,TRANSACTION FEE ", 9, 0, 0, 0, NULL},
/* FIELD 29 */ {0,"AMOUNT,SETTLEMENT FEE ", 9, 0, 0, 0, NULL},
/* FIELD 30 */ {0,"AMOUNT,TRANSACTION PROCESSING FEE ", 9, 0, 0, 0, NULL},
/* FIELD 31 */ {0,"AMOUNT,SETTLEMENT PROCESSING FEE ", 9, 0, 0, 0, NULL},
/* FIELD 32 */ {0,"ACOUIRING INSTITUTION ID. CODE ", 11, 0, 2, 0, NULL},
/* FIELD 33 */ {0,"FORWARDING INSTITUTION ID. CODE ", 11, 0, 2, 0, NULL},
/* FIELD 34 */ {0,"PRIMARY ACCOUNT NUMBER,EXTENDED ", 28, 0, 2, 0, NULL},
/* FIELD 35 */ {0,"TRACK 2 DATA ", 37, 0, 2, 0, NULL},
/* FIELD 36 */ {0,"TRACK 3 DATA ",104, 0, 3, 0, NULL},
/* FIELD 37 */ {0,"RETRIEVAL REFERENCE NUMBER ", 24, 0, 0, 0, NULL},
/* FIELD 38 */ {0,"AUTH. IDENTIFICATION RESPONSE ", 12, 0, 0, 0, NULL},
/* FIELD 39 */ {0,"RESPONSE CODE ", 4, 0, 0, 0, NULL},
/* FIELD 40 */ {0,"SERVICE RESTRICTION CODE ", 3, 0, 0, 0, NULL},
/* FIELD 41 */ {0,"SERVICE CODE ", 16, 0, 0, 0, NULL},
/* FIELD 42 */ {0,"CARD ACCEPTOR IDENTIFICATION CODE ", 30, 0, 0, 0, NULL},
/* FIELD 43 */ {0,"CARD ACCEPTOR NAME/LOCATION ", 40, 0, 0, 0, NULL},
/* FIELD 44 */ {0,"ADDITIONAL RESPONSE DATA ", 50, 0, 2, 0, NULL},
/* FIELD 45 */ {0,"TRACK 1 DATA ", 76, 0, 2, 0, NULL},
/* FIELD 46 */ {0,"ADDITIONAL DATA --- ISO ",999, 0, 3, 0, NULL},
/* FIELD 47 */ {0,"ADDITIONAL DATA --- NATIONAL ",999, 0, 3, 0, NULL},
/* FIELD 48 */ {0,"MOBILE PHONE NUMBER ",999, 0, 3, 0, NULL},
/* FIELD 49 */ {0,"ORIGINAL RRN ", 6, 0, 0, 0, NULL},
/* FIELD 50 */ {0,"MONTH TO BATCH ENQUIRE ", 3, 0, 0, 0, NULL},
/* FIELD 51 */ {0,"CURRENCY CODE,CARDHOLDER BILLING ", 3, 0, 0, 0, NULL},
/* FIELD 52 */ {0,"PERSONAL IDENTIFICATION NUMBER DATA ", 16, 0, 0, 0, NULL},
/* FIELD 53 */ {0,"SECURITY RELATED CONTROL INFORMATION", 16, 0, 0, 0, NULL},
/* FIELD 54 */ {0,"ADDITIONAL AMOUNTS ",120, 0, 3, 0, NULL},
/* FIELD 55 */ {0,"RESERVED ISO ",255, 0, 3, 0, NULL},
/* FIELD 56 */ {0,"RESERVED ISO ",999, 0, 3, 0, NULL},
/* FIELD 57 */ {0,"RESERVED NATIONAL ",999, 0, 3, 0, NULL},
/* FIELD 58 */ {0,"RESERVED NATIONAL ",999, 0, 3, 0, NULL},
/* FIELD 59 */ {0,"RESERVED NATIONAL ",999, 0, 3, 0, NULL},
/* FIELD 60 */ {0,"MOBILE SERIALS NO ", 60, 0, 3, 0, NULL},
/* FIELD 61 */ {0,"RESERVED --- PRIVATE ", 26, 0, 3, 0, NULL},
/* FIELD 62 */ {0,"RESERVED --- PRIVATE ", 50, 0, 3, 0, NULL},
/* FIELD 63 */ {0,"RESERVED --- PRIVATE ", 24, 0, 3, 0, NULL},
/* FIELD 64 */ {0,"MESSAGE AUTHENTICATION CODE FIELD ", 16, 0, 0, 0, NULL},
/* FIELD 65 */ {0,"BIT MAP,EXTENDED ", 8, 0, 0, 0, NULL},
/* FIELD 66 */ {0,"PRIMARY ACCOUNT NUMBER ", 1, 0, 0, 0, NULL},
/* FIELD 67 */ {0,"PROCESSING CODE ", 2, 0, 0, 0, NULL},
/* FIELD 68 */ {0,"AMOUNT, TRANSACTION ", 3, 0, 0, 0, NULL},
/* FIELD 69 */ {0,"AMOUNT, SETTLEMENT ", 3, 0, 0, 0, NULL},
/* FIELD 70 */ {0,"AMOUNT, CARDHOLDER BILLING ", 3, 0, 0, 0, NULL},
/* FIELD 71 */ {0,"TRANSACTION DATE AND TIME ", 4, 0, 0, 0, NULL},
/* FIELD 72 */ {0,"AMOUNT, CARDHOLDER BILLING FEE ", 4, 0, 0, 0, NULL},
/* FIELD 73 */ {0,"CONVERSION RATE,SETTLEMENT ", 6, 0, 0, 0, NULL},
/* FIELD 74 */ {0,"CONVERSION RATE,CARDHOLDER BILLING ", 10, 0, 0, 0, NULL},
/* FIELD 75 */ {0,"SYSTEM TRACE AUDIT NUMBER ", 10, 0, 0, 0, NULL},
/* FIELD 76 */ {0,"TIME, LOCAL TRANSACTION ", 10, 0, 0, 0, NULL},
/* FIELD 77 */ {0,"DATE, LOCAL TRANSACTION ", 10, 0, 0, 0, NULL},
/* FIELD 78 */ {0,"DATE, EXPIRATION ", 10, 0, 0, 0, NULL},
/* FIELD 79 */ {0,"DATE, SETTLEMENT ", 10, 0, 0, 0, NULL},
/* FIELD 80 */ {0,"DATE, CONVERSION ", 10, 0, 0, 0, NULL},
/* FIELD 81 */ {0,"DATE, CAPTURE ", 10, 0, 0, 0, NULL},
/* FIELD 82 */ {0,"MERCHANT'S TYPE ", 12, 0, 0, 0, NULL},
/* FIELD 83 */ {0,"ACQUIRING INSTITUTION COUNTRY CODE ", 12, 0, 0, 0, NULL},
/* FIELD 84 */ {0,"PRIM. ACCNT. NO. EXT.,COUNTRY CODE ", 12, 0, 0, 0, NULL},
/* FIELD 85 */ {0,"FORWARDING INSTITUTION COUNTRY CODE ", 12, 0, 0, 0, NULL},
/* FIELD 86 */ {0,"POINT OF SERVICE ENTRY MODE ", 16, 0, 0, 0, NULL},
/* FIELD 87 */ {0,"CARD SEQUENCE NUMBER ", 16, 0, 0, 0, NULL},
/* FIELD 88 */ {0,"NETWORK INTERNATIONAL IDENTIFIER ", 16, 0, 0, 0, NULL},
/* FIELD 89 */ {0,"POINT OF SERVICE CONDITION CODE ", 16, 0, 0, 0, NULL},
/* FIELD 90 */ {0,"POINT OF SERVICE PIN CAPTURE CODE ", 42, 0, 0, 0, NULL},
/* FIELD 91 */ {0,"AUTH IDENTIFICATION RESPONSE LENGTH ", 1, 0, 0, 0, NULL},
/* FIELD 92 */ {0,"AMOUNT,TRANSACTION FEE ", 2, 0, 0, 0, NULL},
/* FIELD 93 */ {0,"AMOUNT,SETTLEMENT FEE ", 5, 0, 0, 0, NULL},
/* FIELD 94 */ {0,"AMOUNT,TRANSACTION PROCESSING FEE ", 7, 0, 0, 0, NULL},
/* FIELD 95 */ {0,"AMOUNT,SETTLEMENT PROCESSING FEE ", 42, 0, 0, 0, NULL},
/* FIELD 96 */ {0,"ACOUIRING INSTITUTION ID. CODE ", 8, 0, 0, 0, NULL},
/* FIELD 97 */ {0,"FORWARDING INSTITUTION ID. CODE ", 17, 0, 0, 0, NULL},
/* FIELD 98 */ {0,"PRIMARY ACCOUNT NUMBER,EXTENDED ", 25, 0, 0, 0, NULL},
/* FIELD 99 */ {0,"TRACK 2 DATA ", 11, 0, 2, 0, NULL},
/* FIELD 100*/ {0,"TRACK 3 DATA ", 11, 0, 2, 0, NULL},
/* FIELD 101*/ {0,"RETRIEVAL REFERENCE NUMBER ", 17, 0, 2, 0, NULL},
/* FIELD 102*/ {0,"AUTH. IDENTIFICATION RESPONSE ", 28, 0, 2, 0, NULL},
/* FIELD 103*/ {0,"RESPONSE CODE ", 28, 0, 2, 0, NULL},
/* FIELD 104*/ {0,"SERVICE RESTRICTION CODE ",100, 0, 3, 0, NULL},
/* FIELD 105*/ {0,"OPERATOR ID ",999, 0, 3, 0, NULL},
/* FIELD 106*/ {0,"OPERATOR PIN ",999, 0, 3, 0, NULL},
/* FIELD 107*/ {0,"OPERATOR NEW PIN ",999, 0, 3, 0, NULL},
/* FIELD 108*/ {0,"ADDITIONAL RESPONSE DATA ",999, 0, 3, 0, NULL},
/* FIELD 109*/ {0,"TRACK 1 DATA ",999, 0, 3, 0, NULL},
/* FIELD 110*/ {0,"ADDITIONAL DATA --- ISO ",999, 0, 3, 0, NULL},
/* FIELD 111*/ {0,"ADDITIONAL DATA --- NATIONAL ",999, 0, 3, 0, NULL},
/* FIELD 112*/ {0,"ADDITIONAL DATA --- PRIVATE ",100, 0, 3, 0, NULL},
/* FIELD 113*/ {0,"CURRENCY CODE,TRANSACTION ",999, 0, 3, 0, NULL},
/* FIELD 114*/ {0,"CURRENCY CODE,SETTLEMENT ",999, 0, 3, 0, NULL},
/* FIELD 115*/ {0,"CURRENCY CODE,CARDHOLDER BILLING ",999, 0, 3, 0, NULL},
/* FIELD 116*/ {0,"PERSONAL IDENTIFICATION NUMBER DATA ",999, 0, 3, 0, NULL},
/* FIELD 117*/ {0,"SECURITY RELATED CONTROL INFORMATION",999, 0, 3, 0, NULL},
/* FIELD 118*/ {0,"ADDITIONAL AMOUNTS ",999, 0, 3, 0, NULL},
/* FIELD 119*/ {0,"RESERVED ISO ",999, 0, 3, 0, NULL},
/* FIELD 120*/ {0,"RESERVED ISO ",999, 0, 3, 0, NULL},
/* FIELD 121*/ {0,"RESERVED NATIONAL ", 11, 0, 3, 0, NULL},
/* FIELD 122*/ {0,"RESERVED NATIONAL ",999, 0, 3, 0, NULL},
/* FIELD 123*/ {0,"RESERVED NATIONAL ",999, 0, 3, 0, NULL},
/* FIELD 124*/ {0,"RESERVED --- PRIVATE ",999, 0, 3, 0, NULL},
/* FIELD 125*/ {0,"RESERVED --- PRIVATE ",999, 0, 3, 0, NULL},
/* FIELD 126*/ {0,"RESERVED --- PRIVATE ",999, 0, 3, 0, NULL},
/* FIELD 127*/ {0,"RESERVED --- PRIVATE ", 50, 0, 3, 0, NULL},
/* FIELD 128*/ {0,"MESSAGE AUTHENTICATION CODE FIELD ", 8, 0, 0, 0, NULL}
};
char proc[5];
int unpack_master_8583(char *buf)
{
int i, j, k, bit;
char st_len[4];
char ch;
char bitmap[32];
memset(bitmap, 0, sizeof(bitmap));
for(i=0;i<128;i++)
if(master[i].bit_flag == 1){
free(master[i].data);
master[i].data = NULL;
}
if(buf[0] >= '8'){
memcpy(bitmap, buf, 32);
bitmap[31] = '\0';
}else{
memcpy(bitmap, buf, 16);
bitmap[16] = '\0';
}
buf += 16;
for (i=0;i<strle(bitmap);i++)
for(bit=0x08,j=0;j<4;j++,bit/=2){
k = i * 4 + j ;
if(bitmap[i] > 0x40)
ch = bitmap[i] - 7;
else
ch = bitmap[i];
if ((ch & bit) == 0x00){
master[k].bit_flag = 0;
continue;
}else
master[k].bit_flag = 1;
if(master[k].variable_flag > 0){
memset(st_len, 0, sizeof(st_len));
if(master[k].variable_flag == 3)
buf++;
strncpy(st_len, buf, (master[k].variable_flag));
buf = buf + (master[k].variable_flag);
master[k].length = atoi(st_len);
}
if(master[k].attribute)
master[k].length_in_byte = (master[k].length + 1)/2;
else
master[k].length_in_byte = master[k].length;
master[k].data = (char *)malloc(master[k].length_in_byte * sizeof(char)+1);
memcpy(master[k].data,buf,master[k].length_in_byte);
master[k].data[master[k].length_in_byte]=0;
buf += master[k].length_in_byte;
if(master[k].variable_flag > 0){
if(master[k].length % 2 != 0)
buf++;
}else
if(master[k].length % 2 != 0)
buf++;
}
return TRUE;
}
void bcd_to_asc(int n){
#if 1
int i, k = 0;
int len = master[n].length;
char p[1024];
memset(p, '\0', len);
for(i = 0; i < len / 2; i++){
if(master[n].data[i * 2] == '3'){
p[k++] = master[n].data[i * 2 + 1];
}else
p[k++] = master[n].data[i * 2 + 1] - '1' + 'A';
}
p[k++] = '\0';
k = 0;
printf("%d = [%s]\n",n+1,p);
#endif
}
int debug_master_8583()
{
int i;
printf("<========debug master 8583 package begin========>\n");
printf("%d = [%s]\n", 0, proc);
for(i=0;i<128;i++)
if(master[i].bit_flag == 1){
if(i + 1 == 37 || i + 1 == 38 || i + 1 == 39 || i + 1 == 41 || i + 1 == 42
|| i + 1 == 44 || i + 1 == 49 || i + 1 == 63 || i + 1 == 64){
bcd_to_asc(i);
continue;
}
printf("%d = [%s]\n",i+1,master[i].data);
}
printf("<=========debug master 8583 package end=========>\n");
return TRUE;
}
void protocal_master_8583(char *p)
{
strncpy(proc, &p[14], 4);
}
int main(void)
{
// char p[1024] = "005f60000300000200302044c020c08810210009000000000001005018998802100006377689200010172645673d130820147800000000303130303030313230313130303030303130303030303131353626000000000000000011260001100000";
char p[1024] = "008460000300000200302204c030c09811000000000000000001001939081702100006347689100110100001411d9912201143000000347689100110100001411d991220114300003031303339393939313033313130313939393939393939313536b54d0a14d91421ec20000000000000000008220023204533454537434336";
// char p[1024] = "006d600003000002002022048030c080113100000019420817022000347689100110100001411d9912201143000000347689100110100001411d9912201143000030313033393939393130333131303139393939393939393135360008010023203941444630393639";
protocal_master_8583(p);
unpack_master_8583(&p[18]);
debug_master_8583();
return 0;
}
下面是 “iso8583_gm.h” 头文件
#ifndef _ISO8583_H_
#define _ISO8583_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curses.h>
struct ISO8583 {
short bit_flag; /* 位图位 */
char data_name[37]; /* 域 名 */
short length; /* 长 度 */
short attribute; /* 属 性 */
short variable_flag; /* 变 长 */
short length_in_byte; /* 变长长度 */
char *data; /* 域的数据 */
};
extern struct ISO8583 master[128];
extern int unpack_master_8583(char *buf);
extern void protocal_master_8583(char *p);
extern int debug_master_8583();
extern void bcd_to_asc(int n);
#endif
下面是我写的一个简单的Makefile
app:iso8583_gm.o
gcc $< -o $@ -g -Wall
iso8583_gm.o:iso8583_gm.c
gcc $< -c
clean:
rm *.o app
.PHONY: clean
小弟刚任职,还没毕业,代码风格,代码优化,还有代码的全面程度都不是很好,希望各位高手指点迷津。由于这个格式很难调,本人把注释删了,忘大家谅解。可以下载附件观看。
转载于:https://blog.51cto.com/4585258/837539