ISO8583报文拆解 C语言简单实现

 

/* ===========================================================>>

  *  文件名: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;

}

 

下面是 &ldquo;iso8583_gm.h&rdquo; 头文件

#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

 

小弟刚任职,还没毕业,代码风格,代码优化,还有代码的全面程度都不是很好,希望各位高手指点迷津。由于这个格式很难调,本人把注释删了,忘大家谅解。可以下载附件观看。

 

你可能感兴趣的:(c)