8583协议深入理解 1

深入理解8583协议

最初,金融系统只有IBM这些大公司来提供设备,象各种主机与终端等,后来有很多大大小小的公司进入,怎样设计一个报文协议,解决各公司金融系统之间的报文交换,暂且称该协议叫做ISO8583协议。例如‘回头客会员管理系统’POS机上应用的就是8583报文。

金融行业涉及到的数据内容是比较少的,如交易类型、帐号、帐户类型、密码、交易金额、交易手续费、日期时间、商户代码、23磁数据、交易序列号等,都总结起来不过100个左右的数据。我们可以简单的设计ISO8583,定义128个字段,将所有金融数据字段按照顺序排列,分别对应128个字段。每个数据类型占固定的长度,要发送一个报文时,就将128个字段按照顺序连起来,然后将整串数据包发送出去。

任何金融软件收到ISO8583包后,直接按照我们定义的规范解包即可,因为整个报文的128个字段都预先定义好了。比如第1个字段是交易类型,长度为4位,第2个字段位是帐号,为19位等等。接收方就可以先取4位,再取接着的19位,依次类推,直到整个数据包128个字段都解完为止。
     
不过我们有几个问题要思考下:
1
、 我怎么知道每个字段的数据类型呢,是数字还是字符?
2
、 每个传送的报文都把128个字段都传过去,有时候我可能只需要其中5个字段。
3
、 如果我某些字段的长度不固定,属于变长怎么办。
   
第一个问题。我在定义ISO8583时除了定义每个字段表示什么,还规定其内容是数字或是字符等类型。可能出现的类型有以下几种:字母、数字、特殊字符、年月日等时间、二进制数据。比如商户类型字段定义其长度是15,类型为字母。如果商户类型同时包括数字和字母呢?那我们就定义一个字段可以同时属于多个类型。
   
第二个问题。其本质就是如果我只传128个字段的5个字段,接收方怎么知道我传了哪几个字段。我在报文前面加上个包头,用16个字节,即128bit来表示128个字段中的某个字段是否存在。每个bit如果是1就表示对应的字段在本次报文中存在,如果是0就是不存在。比如,我要发送5个字段,分别属于128个字段中的第23689字段,我就可以将128bit的报文头填成011001011000000000………0
    
我们把这16个字节称为bit map,即位图,用来表示某个位是否存在。考虑到很多时候报文不需要128个字段,可以将报文头由128bit减到64bit,把ISO8583128个字段中最常见的都放到前64个字段中,只有在需要的时候才把剩下的64bit放到报文里面?

我把64bit报文头的第一位bit用来代表特殊含义,如果该bit1,则表示64bit后面跟了剩下的64bit报文头;如果第一位bit0,则表示64bit后面直接是数据字段内容。因为报文头第二个64bit属于有时候有,所以我们叫它Extended bit map扩展位图,报文头最开始的64bit我们叫它Primary bit map主位图。我们直接把扩展位图固定放到128个字段的第一个字段,而主位图每个数据包都有,就强制性放在所有128个字段的前面。
   
第三个问题。比如第2个字段是帐号,是不定长的,可能有的银行帐号是19位,有的是17位等,在字段的开头加上帐号的长度。比如帐号是0123456789,一共10位,我们变成100123456789,接收方收到该字段后,它知道ISO8583规定第2个字段帐号是变长的,会先取前面2位出来,然后根据长度获取帐号。在规范里面定义某个字段的属性是“LLVAR”,其中LL表示长度,VAR表示数据,两个LL表示两位长,最大是99,三位就是“LLLVAR”,最大是999

另外考虑到有些人有特殊的要求,我们将128个字段中的部分定义为自定义字段,算是一种扩展。

 

字段域的定义

  typedef struct ISO8583

  {

  int bit_flag; /*域数据类型0 -- string, 1 -- int, 2 -- binary*/

  char *data_name; /*域名*/

  int length; /*数据域长度*/

  int length_in_byte;/*实际长度(如果是变长)*/

  int variable_flag; /*是否变长标志0:否 22位变长, 33位变长*/

  int datatyp; /*0 -- string, 1 -- int, 2 -- binary*/

  char *data; /*存放具体值*/

  int attribute; /*保留*/

  } ISO8583;

  ISO8583 Tbl8583[128] =

  {

  /* FLD 1 */ {0,"BIT MAP,EXTENDED ", 8, 0, 0, 2, NULL,0},

  /* FLD 2 */ {0,"PRIMARY ACCOUNT NUMBER ", 22, 0, 2, 0, NULL,0},

  /* FLD 3 */ {0,"PROCESSING CODE ", 6, 0, 0, 0, NULL,0},

  /* FLD 4 */ {0,"AMOUNT, TRANSACTION ", 12, 0, 0, 1, NULL,0},

  /* FLD 5 */ {0,"NO USE ", 12, 0, 0, 0, NULL,0},

  /* FLD 6 */ {0,"NO USE ", 12, 0, 0, 0, NULL,0},

  /* FLD 7 */ {0,"TRANSACTION DATE AND TIME ", 10, 0, 0, 0, NULL,0},

  /* FLD 8 */ {0,"NO USE ", 8, 0, 0, 0, NULL,0},

  /* FLD 9 */ {0,"NO USE ", 8, 0, 0, 0, NULL,0},

  /* FLD 10 */ {0,"NO USE ", 8, 0, 0, 0, NULL,0},

  /* FLD 11 */ {0,"SYSTEM TRACE AUDIT NUMBER ", 6, 0, 0, 1, NULL,0},

  /* FLD 12 */ {0,"TIME, LOCAL TRANSACTION ", 6, 0, 0, 0, NULL,0},

  /* FLD 13 */ {0,"DATE, LOCAL TRANSACTION ", 4, 0, 0, 0, NULL,0},

  /* FLD 14 */ {0,"DATE, EXPIRATION ", 4, 0, 0, 0, NULL,0},

  /* FLD 15 */ {0,"DATE, SETTLEMENT ", 4, 0, 0, 0, NULL,0},

  /* FLD 16 */ {0,"NO USE ", 4, 0, 0, 0, NULL,0},

  /* FLD 17 */ {0,"DATE, CAPTURE ", 4, 0, 0, 0, NULL,0},

  /* FLD 18 */ {0,"MERCHANT'S TYPE ", 4, 0, 0, 0, NULL,0},

    //省略部分参考规范文档。

  /* FLD 123 */ {0,"NEW PIN DATA ", 8, 0, 3, 2, NULL,0},

  /* FLD 124 */ {0,"NO USE ",999, 0, 3, 0, NULL,0},

  /* FLD 125 */ {0,"NO USE ",999, 0, 3, 0, NULL,0},

  /* FLD 126 */ {0,"NO USE ",999, 0, 3, 0, NULL,0},

  /* FLD 127 */ {0,"NO USE ",999, 0, 3, 0, NULL,0},

/* FLD 128 */ {0,"MESSAGE AUTHENTICATION CODE FIELD ", 8, 0, 0, 2, NULL,0}

  };

  如第二域:域名为主帐号,

  数据类型为string

  长度为22(最长长度不得超过此数)

  是个2位变长域

  在打包时需在数据域前加上数据的实际长度,如‘19数据值’(即19为长度)

  如第三域:域名为处理码,

  数据类型为string

  长度为6

  是个定长域 必须填满6位。

1,信息类型(message type)定义

位图位置:-

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值