金融系統中BER-TLV的解析,更改、增加、刪除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
   }
]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM