8583报文解析

来源:互联网 发布:sql if两个判断 编辑:程序博客网 时间:2024/05/22 03:14

8583报文解析

By it_zujun(JK Landy) 
一个人的战争(http://blog.csdn.net/u013634862/
在金融行业中数据的传递、安全尤为重要,本文根据8583协议对任意交易进行了报文的一个解析,报文解析设计逻辑仅供参考。首先需要分析报文的组成:报文:报文长度(2) + TPDU(5) + 报文头(6) + 应用数据(.....)应用数据包含各个域的值,不同交易由不同的域组成,其中有的域是固定长度,有的域是可变长度域域的组成:长度固定域:根据银联规范,其长度固定可变域:长度值+数据值交易的分布由Bitmap标识,因此我们可以更具一个完整的域表来维护我们的报文解析,就思路如下。首先我们将我们的接收交易数据存放到一个数组中,由于报文长度、TPDU、报文头的长度固定,我们直接可以直接定位到数据域中,直接获取Bitmap值,我们用一个结构体来指定各个域的位置和长度就可以任意提取我们的数据值了。/报文域的属性描述。

struct data_config {    unsigned int seat;  //域的启始位置     unsigned int len;    //域的长度};

通过统计阅读银联文档,统计每个域的属性(定长、长度可变、压缩BCD码、ASSIC码等)。

    unsigned char Area[65] = { 0, 100,  53,  3,  6,  100,  100,  100,  100,      // 1-8                        100,100, 3,  3,  2,    2,    2,    100,   // 9-16                        100,100, 100,100,100,  2,    2,    100,    // 17-24mZ                                             1,  1,   100,100,100,  100,  100,  53,     // 25-32                        100,100, 53, 63, 12,   6,    2,    100,     // 33-40                        8,  15,  100,52, 100,  100,  100,  63,     // 41-48                        3,  100, 100,8,  8,    62,   63,   100,    // 49-56                        100,62,  100,63, 63,   62,   62,   8};     // 57-64

上图为银联规范中的各个域的长度值,为了方便我们做了一下约定,其中数组的位置代表每一个域,定义了65个char,我们采取Area[1]—Area[64]

100:银联中还没有定义的域1-30:固定长度域,值代表域的长度值,如Area[41]的值为8,则41域为定长为8个字节的域52:代表可变域,1个字节代表长度,数据域为ASSIC码存放53:代表可变域,1个字节代表长度,数据域为BCD码存放62:代表可变域,2个字节代表长度,数据域为ASSIC码存放, 如:58域63:代表可变域,2个字节代表长度,数据域为BCD码存放, 如60域通过解析Bitmap将64个data_config完整填写,就能进行随时调用各个域的值。struct data_config config[65]; //64个域的属性数组

下面是我写的代码:

/*************************************************************************> File Name: data_8583> Author: it_zujun> Mail: > Created Time: 2015年09月04日 星期五 09时22分08秒 ************************************************************************/#include<stdio.h>struct data_config {    unsigned int seat;    unsigned int len;};int main(int argc, char *argv[]){    //报文长度查阅表     //100 表示未定有    //<20的代表定长    //52  其中5代表长度可变域中1个字节代表长度,2代表数据域为ASSIC码,3代表BCD压缩数据    //63  其中6代表长度可变域中2个字节代表长度,<span style="font-family: Arial, Helvetica, sans-serif;">2代表数据域为ASSIC码,3代表BCD压缩数据</span>    //............................    unsigned char Area[65] = { 0, 100,  53,  3,  6,  100,  100,  100,  100,      // 1-8                        100,100, 3,  3,  2,    2,    2,    100,   // 9-16                        100,100, 100,100,100,  2,    2,    100,    // 17-24mZ                                             1,  1,   100,100,100,  100,  100,  53,     // 25-32                        100,100, 53, 63, 12,   6,    2,    100,     // 33-40                        8,  15,  100,52, 100,  100,  100,  63,     // 41-48                        3,  100, 100,8,  8,    62,   63,   100,    // 49-56                        100,62,  100,63, 63,   62,   62,   8};     // 57-64    unsigned data_8583[1024] = {        0x01, 0x1A, 0x60, 0x00, 0x00, 0x00, 0x02, 0x60, 0x31, 0x00, //1        0x31, 0x10, 0x04, 0x02, 0x10, 0x70, 0x3E, 0x00, 0xC1, 0x0E, //2        0xD0, 0x8C, 0x17, 0x19, 0x62, 0x28, 0x48, 0x02, 0x11, 0x39, //3        0x79, 0x24, 0x91, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         0x00, 0x50, 0x00, 0x00, 0x00, 0x29, 0x09, 0x39, 0x29, 0x09,         0x04, 0x49, 0x12, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01,         0x00, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,         0x39, 0x30, 0x31, 0x32, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,         0x30, 0x30, 0x00 ,0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x30, 0x31, 0x30, 0x33,        0x30, 0x30, 0x30, 0x30, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30,         0x33, 0x30, 0x30, 0x30, 0x30, 0x31, 0x35, 0x36, 0x26, 0x00,         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x39, 0x30,         0x30, 0x32, 0x31, 0x35, 0x36, 0x43, 0x30, 0x30, 0x30, 0x30,         0x30, 0x32, 0x35, 0x36, 0x33, 0x32, 0x31, 0x35, 0x00, 0x14,         0x22, 0x00, 0x00, 0x01, 0x00, 0x06, 0x01, 0x00, 0x72, 0x30,         0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x35, 0x30, 0x30, 0x30,         0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x32, 0x30,         0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x32, 0x35, 0x30,         0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,         0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,         0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,         0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,         0x30, 0x00, 0x33, 0x43, 0x55, 0x50, 0x41, 0x4E, 0xB8, 0xF1,         0xCD, 0xDF, 0xC0, 0xAD, 0xD1, 0xA1, 0x41, 0x42, 0xD2, 0xF8,         0xC1, 0xAA, 0xD4, 0xDA, 0xCF, 0xDF, 0xD6, 0xA7, 0xB8, 0xB6,         0xCD, 0xDF, 0xC0, 0xAD, 0xD1, 0xA1, 0x45, 0x31, 0x33, 0x35, //28        0x35, 0x32, 0x41, 0x32                                      //29    };    unsigned char i, j, seek_i, num, check, count;    struct data_config tab;    unsigned char   location_data[8];    struct data_config config[65];    unsigned int temp;    tab.seat = 10;    tab.len = 11;    int all_size; // the size of 8583_data    all_size = data_8583[0]*256 + data_8583[1];    printf("the sizeof 8583 = %d\n",all_size);    printf("TPDU:");    for (i=0; i<5; i++)    {        printf("%02x",data_8583[2+i]);    }        printf("\nhead:");    for (i=0; i<6; i++)    {        printf("%02x",data_8583[i+7]);    }    printf("\n");        printf("tpye:");    for (i=0; i<2; i++)    {        printf("%02x",data_8583[i+13]);    }    printf("\nlocation data:");        for (i=0; i<8; i++)    {        location_data[i] = data_8583[15+i];        printf("%02x",location_data[i]);    }    printf("\n");    for (i=0; i<64; i++)    {        config[i].seat = 0;        config[i].len = 0;    }    temp = 23;    printf("the first data temp = %02x\n",data_8583[temp]);    for (i=0; i<8; i++)    {        seek_i = location_data[i];         for (j=0; j<8; j++)        {            check = 0x00;            check = seek_i & 0x80;            if(check == 0x80)            {                if (Area[i*8+j+1] == 100)                {                    continue;                }                 else if (Area[i*8+j+1] == 52 || Area[i*8+j+1] == 53)                {                    if(Area[i*8+j+1] == 52)                    {                        count = 0;                        count = (data_8583[temp]>>4)*10 + (data_8583[temp]&0x0f);                        config[i*8+j+1].seat = temp;                        config[i*8+j+1].len = count+1;                        temp = temp + count + 1;                    }                    if(Area[i*8+j+1] == 53)                    {                        count = 0;                        count = ( (data_8583[temp]>>4)*10 + (data_8583[temp] & 0x0f) + 1) / 2;                        config[i*8+j+1].seat = temp;                        config[i*8+j+1].len = count+1;                        temp = temp + count + 1;                    }                }                 else if(Area[i*8+j+1] == 62 || Area[8*i+j+1] == 63)                {                    if(Area[i*8+j+1] == 62)                    {                        count = 0;                        count =  (data_8583[temp]&0x0f)*100  + (data_8583[temp+1]>>4)*10 + (data_8583[temp+1]&0x0f);                        config[i*8+j+1].seat = temp;                        config[i*8+j+1].len = count+2;                        temp = temp + count +2;                    }                    if(Area[i*8+j+1] == 63)                    {                        count = 0;                        count = ( (data_8583[temp]&0x0f)*100  + (data_8583[temp+1]>>4)*10 + (data_8583[temp+1]&0x0f) ) / 2;                        config[i*8+j+1].seat = temp;                        config[i*8+j+1].len = count + 2;                        temp = temp + count + 2;                    }                } else {                                        count = Area[i*8+j+1];                    config[i*8+j+1].len = count;                    config[i*8+j+1].seat = temp;                    temp = temp + count;                }            }            seek_i = seek_i<<1;        }    }    for (i=1; i<65; i++)    {        if(config[i].len != 0)        {            printf("%d:",i);            for (j=0; j<config[i].len; j++)            {                printf(" %02x", data_8583[config[i].seat + j]   );            }            printf("\n");        }    }     return;}   //



为了达到移植通用性,报文解析做了一下修改:

/*参数介绍:struct data_config* config  :报文指针unsigned char* location_data: bitmap指针char* Area: 报文域属性表调用 eg:   data_8583_config(config_8583, location_data_8583, Area_8583);*/void data_8583_config(struct data_config* config, unsigned char* location_data, char* Area){unsigned char i, j, count, seek_i, check;    int all_size; // the size of 8583_dataunsigned int temp;   // all_size = data_8583[0]*256 + data_8583[1];    printf("the sizeof 8583 = %d\n",all_size);    printf("TPDU:");    for (i=0; i<5; i++)    {        printf("%02x",data_8583[2+i]);    }        printf("\nhead:");    for (i=0; i<6; i++)    {        printf("%02x",data_8583[i+7]);    }    printf("\n");        printf("tpye:");    for (i=0; i<2; i++)    {        printf("%02x",data_8583[i+13]);    }    printf("\nlocation data:");        for (i=0; i<8; i++)    {        location_data[i] = data_8583[15+i];        printf("%02x",location_data[i]);    }    printf("\n");    for (i=0; i<64; i++)    {        config[i].seat = 0;        config[i].len = 0;    }    temp = 23;    printf("the first data temp = %02x\n",data_8583[temp]);    for (i=0; i<8; i++)    {        seek_i = location_data[i];         for (j=0; j<8; j++)        {            check = 0x00;            check = seek_i & 0x80;            if(check == 0x80)            {                if (Area[i*8+j+1] == 100)                {                    continue;                }                 else if (Area[i*8+j+1] == 52 || Area[i*8+j+1] == 53)                {                    if(Area[i*8+j+1] == 52)                    {                        count = 0;                        count = (data_8583[temp]>>4)*10 + (data_8583[temp]&0x0f);                        config[i*8+j+1].seat = temp;                        config[i*8+j+1].len = count+1;                        temp = temp + count + 1;                    }                    if(Area[i*8+j+1] == 53)                    {                        count = 0;                        count = ( (data_8583[temp]>>4)*10 + (data_8583[temp] & 0x0f) + 1) / 2;                        config[i*8+j+1].seat = temp;                        config[i*8+j+1].len = count+1;                        temp = temp + count + 1;                    }                }                 else if(Area[i*8+j+1] == 62 || Area[8*i+j+1] == 63)                {                    if(Area[i*8+j+1] == 62)                    {                        count = 0;                        count =  (data_8583[temp]&0x0f)*100  + (data_8583[temp+1]>>4)*10 + (data_8583[temp+1]&0x0f);                        config[i*8+j+1].seat = temp;                        config[i*8+j+1].len = count+2;                        temp = temp + count +2;                    }                    if(Area[i*8+j+1] == 63)                    {                        count = 0;                        count = ( (data_8583[temp]&0x0f)*100  + (data_8583[temp+1]>>4)*10 + (data_8583[temp+1]&0x0f) ) / 2;                        config[i*8+j+1].seat = temp;                        config[i*8+j+1].len = count + 2;                        temp = temp + count + 2;                    }                } else {                                        count = Area[i*8+j+1];                    config[i*8+j+1].len = count;                    config[i*8+j+1].seat = temp;                    temp = temp + count;                }            }            seek_i = seek_i<<1;        }    }}


//代码备注较少请大家谅解

图1 代码展示


图2 报文解析运行结果

银联处理中心报文:接收报文:======================================01 1A 60 00 00 00 02 60 31 00 31 10 04 02 10 70 3E 00 C1 0E D0 8C 17 19 62 28 48 02 11 39 79 24 91 40 00 00 00 00 00 00 00 50 00 00 00 29 09 39 29 09 04 49 12 00 00 00 00 08 00 01 00 00 31 32 33 34 35 36 37 38 39 30 31 32 31 32 33 34 35 36 30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19 30 31 30 33 30 30 30 30 20 20 20 30 31 30 33 30 30 30 30 31 35 36 26 00 00 00 00 00 00 00 00 20 39 30 30 32 31 35 36 43 30 30 30 30 30 32 35 36 33 32 31 35 00 14 22 00 00 01 00 06 01 00 72 30 30 30 30 30 30 32 35 30 30 30 30 30 30 30 30 30 30 31 32 30 30 30 30 30 30 30 31 32 35 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 00 33 43 55 50 41 4E B8 F1 CD DF C0 AD D1 A1 41 42 D2 F8 C1 AA D4 DA CF DF D6 A7 B8 B6 CD DF C0 AD D1 A1 45 31 33 35 35 32 41 32标准结果:MSG TYPE:0210BITMAP:703E00C10ED08C172域:19622848021139792491403域:0000004域:00000000500011域:00002912域:09392913域:090414域:491215域:000025域:0026域:0032域:080001000037域:31323334353637383930313238域:31323334353639域:303041域:000000000000000042域:00000000000000000000000000000044域:193031303330303030202020303130333030303049域:31353653域:260000000000000054域:0020393030323135364330303030303235363332313560域:00142200000100060162域:007230303030303032353030303030303030303031323030303030303031323530303030303030303030303030303030303030303030303030303030303030303030303030303030303063域:0033435550414EB8F1CDDFC0ADD1A14142D2F8C1AAD4DACFDFD6A7B8B6CDDFC0ADD1A164域:4531333535324132
0 0
原创粉丝点击