• 金融系统中BERTLV的解析,更改、增加、删除TAG的实现


    金融系统中BER-TLV是一个常用的数据交换协议,TLV是(TAG-LENGTH-VALUE)的缩写,其具体的规范在ISO7616-4中有明确的定义。目前简单描述下关于TLV的编码规则,下文所有的数据表示均为16进制编码。

    TAG域:

    TAG域的第一个字节编码

    TAG域的第二个字节编码

    其中注意第一个字节的第六位,其分为基本数据对象和结构数据对象。简单解释下基本数据对象和结构数据对象,简单举两个例子,下面几个都是符合tlv编码的数据流:

    70069F3803010203

    9F3803010203

    可以看到,70 TAG的值(value)域也是由TLV结构组成的。

    而9F38 TAG的值域则是由简单数据构成(010203)不需要符合TLV结构编码。

    基于这个原则,TLV可以设计成多层嵌套的关系。

    例如:

    6F30840E325041592E5359532E4444463031A51EBF0C1B61194F08A000000333010101500A50424F43204445424954870101

    如果解析嵌套,可以如下表示(以缩进关系表示嵌套关系)

    6F(TAG)

      30(6F的LEN域)

        840E325041592E5359532E4444463031A51EBF0C1B61194F08A000000333010101500A50424F43204445424954870101(6F的VALUE域)

        84(TAG)

          0E(84的LEN域)

            325041592E5359532E4444463031(84的VALUE域)

        A5(TAG)

          1E(A5的LEN域)

            BF0C1B61194F08A000000333010101500A50424F43204445424954870101(A5的VALUE域)

            BF0C(TAG)

             1B(BFOC的LEN域)

              61194F08A000000333010101500A50424F43204445424954870101(BFOC的VALUE域)

              61(TAG)

               19(61的LEN域)

                   4F08A000000333010101500A50424F43204445424954870101(61的VALUE域)

                 4F(TAG)

                  08(4F的LEN域)  

                    A000000333010101(4F的VALUE域)

                                       50(TAG)

                  0A(50的LEN域)

                    50424F43204445424954(50的VALUE域)

                87(TAG)

                  01(87的LEN域)

                    01(87的VALUE域)

    讲完了TAG域,下面简单说明下长度(LEN)域,长度域相比TAG域简单多了,ISO的原文就能很好的说明问题了。

    讲完了TLV的基本结构,现在来讲讲目前设计的实现。目前网上实现的TLV代码也很多,但是很多是基于解析的,没有搜索到有关是基于修改的。

    因为TVL存在嵌套结构,因此一个多层嵌套的TLV结构被更改了,可能会导致一连串的TLV结构LEN域和值域都需要修改。还是上文的那个6FTLV结构为例,如果底层的87被改了,那么除了和他同级别的50、4F和简单结构的84是不需要改变的,其包含了他的所有嵌套结构的TLV结构,都需要改变(6F\A5\BFOC\61),而不巧,本人碰到了多次需要改变该值的情况,特别如果是长度变化了,那整个TLV结构的长度都需要重新算,比较痛苦,因此就设计了以下的模式。

    上面是简单介绍TLV和一些前因后果,下面是实现。

    ====================================================================

    从上文的分析中可以看到,针对一个复合的tlv结构,那么他可以抽象成存在他的值域全是他的下层TLV结构。而一个简单的TLV机构,则可以抽象成他没有下层TLV结构。而真对一个TLV数据串,就可以抽象成多个复杂TLV机构或者简单TLV结构的首尾拼接,各个TLV段之间是平级的。

    这个抽象是不是很像二叉树,因此,就考虑用二叉树的方式去实现这个结构,目前定义的为左边的节点均是他的兄弟(同一级别),右边的节点均是他的儿子(他的下级),由此针对上文的6F,抽象成树的结构就是如下图示:

    因此,如果我们如果需要求一个简单结构的值,则只需要将值直接放在节点上,如果需要求一个复杂结构的值,只需要把它的儿子做一个左右中遍历(将简单机构直接连接成tlv串,如果是复杂结构则直接取之前的串加上自己的TAG和LENGTH)就能够获得他的value了。

    如果是增加一个TLV结构,例如我需要再插入一个A5,其值为9F380101,在原有的84后A5前,则我需要将这个A5首先构造成一个串,然后将左子树连新的A5,将老的A5变为新的A5的左子树,其变化图如下:

                                            

    当然如果是简单结构,那就直接是树的节点的插入,这边就不在说了。

    当然,删除也就是插入的逆向操作,这里也不说了。(嘿嘿,偷懒下了)

    最后,程序的输出可以是XML或者JSON的显示,由于目前项目的选择,列子就以JSON的表示了:

    插入之前:

    [
       {
          "funccode" : 0
       },
       [
          {
             "6F" : "840E325041592E5359532E4444463031A51EBF0C1B61194F08A000000333010101500A50424F43204445424954870101",
             "tlvstr" : "6F30840E325041592E5359532E4444463031A51EBF0C1B61194F08A000000333010101500A50424F43204445424954870101"
          },
          [
             {
                "84" : "325041592E5359532E4444463031",
                "tlvstr" : "840E325041592E5359532E4444463031"
             },
             {
                "A5" : "BF0C1B61194F08A000000333010101500A50424F43204445424954870101",
                "tlvstr" : "A51EBF0C1B61194F08A000000333010101500A50424F43204445424954870101"
             },
             [
                {
                   "BF0C" : "61194F08A000000333010101500A50424F43204445424954870101",
                   "tlvstr" : "BF0C1B61194F08A000000333010101500A50424F43204445424954870101"
                },
                [
                   {
                      "61" : "4F08A000000333010101500A50424F43204445424954870101",
                      "tlvstr" : "61194F08A000000333010101500A50424F43204445424954870101"
                   },
                   [
                      {
                         "4F" : "A000000333010101",
                         "tlvstr" : "4F08A000000333010101"
                      },
                      {
                         "50" : "50424F43204445424954",
                         "tlvstr" : "500A50424F43204445424954"
                      },
                      {
                         "87" : "01",
                         "tlvstr" : "870101"
                      }
                   ]
                ]
             ]
          ]
       ]
    ]

    插入之后

    [
       [
          {
             "6F" : "840E325041592E5359532E4444463031A5049F380101A51EBF0C1B61194F08A000000333010101500A50424F43204445424954870101",
             "tlvstr" : "6F36840E325041592E5359532E4444463031A5049F380101A51EBF0C1B61194F08A000000333010101500A50424F43204445424954870101"
          },
          [
             {
                "84" : "325041592E5359532E4444463031",
                "tlvstr" : "840E325041592E5359532E4444463031"
             },
             {
                "A5" : "9F380101",
                "tlvstr" : "A5049F380101"
             },
             [
                {
                   "9F38" : "01",
                   "tlvstr" : "9F380101"
                }
             ],
             {
                "A5" : "BF0C1B61194F08A000000333010101500A50424F43204445424954870101",
                "tlvstr" : "A51EBF0C1B61194F08A000000333010101500A50424F43204445424954870101"
             },
             [
                {
                   "BF0C" : "61194F08A000000333010101500A50424F43204445424954870101",
                   "tlvstr" : "BF0C1B61194F08A000000333010101500A50424F43204445424954870101"
                },
                [
                   {
                      "61" : "4F08A000000333010101500A50424F43204445424954870101",
                      "tlvstr" : "61194F08A000000333010101500A50424F43204445424954870101"
                   },
                   [
                      {
                         "4F" : "A000000333010101",
                         "tlvstr" : "4F08A000000333010101"
                      },
                      {
                         "50" : "50424F43204445424954",
                         "tlvstr" : "500A50424F43204445424954"
                      },
                      {
                         "87" : "01",
                         "tlvstr" : "870101"
                      }
                   ]
                ]
             ]
          ]
       ],
       {
          "funccode" : 0
       }
    ]
  • 相关阅读:
    人脸旋转 《转》
    深度学习如何入门?<知乎>
    openGL-------------别人的博客
    如何实现视频的快进快退功能(转)
    MFC+OpenGL基础绘制<转>
    野蒜
    人脸识别68个点<转>
    cv::circle《转》
    HTML5 Canvas之猜数字游戏
    LIRe 源代码分析 3:基本接口(ImageSearcher)
  • 原文地址:https://www.cnblogs.com/highkgao/p/3968086.html
Copyright © 2020-2023  润新知