金融系统中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
   }
]
时间: 2024-11-06 15:38:23

金融系统中BER-TLV的解析,更改、增加、删除TAG的实现的相关文章

应用系统中交互式报表功能解析

从报表需求的整个发展历程来看,可以分为两个阶段: 1.静态报表:解决显示.打印.导出报表数据的需要. 2.交互式报表:解决终端用户分析数据的需要,通常会用到数据可视化.向下钻取.贯穿钻取.数据过滤.数据排序等功能. 这篇文章主要介绍交互式报表中常用到的数据分析方法. (一) 数据可视化 数据可视化技术是将数据以图形化的方式进行显示,让数据更易于阅读.理解和分析.早期的数据可视化以图表(Chart)为主,现代商业报表中逐渐加入迷离图(Sparkline).数据条(Bullet).图标集(Icon)

win7系统中的软件的系统服务该如何删除

不太懂电脑的用户可能会遇到这样的问题,明明一个软件卸载了,但软件的系统服务仍在系统中,这也直接影响了系统的运行速度.为什么会出现这样的问题呢?其实,卸载软件的时候我们一般也需要删除掉软件的系统服务.那么问题来了,Win7怎么删除系统服务?下面就给大家介绍一下方法.1.组合键:win+R,输入"services.msc"命令,打开服务列表,查看系统服务实际的名称: 2.然后重新组合键win+R,输入cmd确定打开,再输入"sc delete [service name]&quo

(3)MEF插件系统中通信机制的设计和实现

1.背景 一般的WinForm中通过C#自带的Event机制便能很好的实现事件的注册和分发,但是,在插件系统中却不能这么简单的直接用已有的类来完成.一个插件本不包含另外一个插件,它们均是独立解耦的,实现插件和插件间的通信还需要我们设计出一个事件引擎来完成这个需求. 目前很多高级语言中基本都实现了观察者模式,并进行了自己的包装.比如C#中的delegate和event组合,java awt中的Event和addActionListener组合,Flex中的Event.addEventListene

报表应用系统中怎样正确使用图表功能

相信对于报表应用系统研发人员而言.都不会对图表功能感到陌生.由于报表数据通常以图表和表格的形式显示.可是.你真的了解为什么须要使用图表功能吗.不同图表类型的最佳应用场景?本文将为你解开这些谜团. (一) 为什么须要使用图表功能 图表是一种将数据以图形方式显示的可视化手段,多用于实现下面需求: 1. 让数据更易于阅读和理解 2. 展示数据数据对照 3. 发挥数据的影响力 4. 将原始数据转换为实用的管理决策信息 当数据变得易于阅读和理解时.我们就easy记住它,并在以后使用到这些数据,充分发挥数据

实现业务系统中的用户权限管理--实现篇

在设计篇中,我们已经为大家阐述了有关权限管理系统的数据库设计,在本篇中,我们将重点放在其实现代码部分.为了让你能够更直接更有效的看到全部动作的代码,我们使用"动作分解列表"的方式来陈述每个动作以及相关资源. 实现权限管理功能的动作 动作分解 动作名 相关表名 操作集类型 (S,U,I,D,SQL) 表单 模组 字符资源 是否分页? 返回提示? 权限检测 权限初始化安装 setup 无 无 无 setup setupok 否 否 否 显示添加管理组界面 addnewgroup 无 无 a

XP系统中,系统属性→计算机名中,网络ID是灰色的不可用状态,还有下面的“更改”按钮点进去,“隶属于”的域和工作组也是灰色不可用

XP系统中,系统属性→计算机名中,网络ID那个按钮是灰色的不可用状态,还有下面的“更改”按钮点进去,“隶属于”的域和工作组也是灰色不可用. 一般提供的解决方法:在运行中键入Msconfig,在服务标签中钩选workstation服务,即可!另,也可在控制面板中选择“管理工具”---“服务”----开启workstation服务即可! 假如没有workstation服务,请在网络中安装microsoft网络客户端! 但是在启用服务的时候却出现问题了:windows 不能在本地计算机中启用 work

【转】Spark Streaming 实时计算在甜橙金融监控系统中的应用及优化

系统架构介绍 整个实时监控系统的架构是先由 Flume 收集服务器产生的日志 Log 和前端埋点数据, 然后实时把这些信息发送到 Kafka 分布式发布订阅消息系统,接着由 Spark Streaming 消费 Kafka 中的消息,同时消费记录由 Zookeeper 集群统一管理,这样即使 Kafka 宕机重启后也能找到上次的消费记录继而进行消费.在这里 Spark Streaming 首先从 MySQL 读取规则然后进行 ETL 清洗并计算多个聚合指标,最后将结果的一部分存储到 Hbase

[转]iOS中UITextField 使用全面解析

001//初始化textfield并设置位置及大小002  UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 130, 30)];003  004//设置边框样式,只有设置了才会显示边框样式 005  text.borderStyle = UITextBorderStyleRoundedRect;006 typedef enum {007    UITextBorderStyleNone,008   

不同于Windows的Linux系统中命令运用(一)

今天介绍的是linux系统中命令运用.与Windows系统不同,Linux系统更多是在命令行下面进行管理与配置. 一.简介: Linux操作系统由Linux内核和各种外围程序组成.内核用于实现CPU.内存分配.进程调度.设备驱动等核心操作,面向硬件为主:外围程序包括分析用户指令的解释器.网络服务程序.图形桌面程序等各种应用软件程序,面向用户为主. Linux系统的发行版本有以下三个:1.Red Hat系列2.Debian系列3.Ubuntu系列发行版的名称.版本由发行厂商决定. GPL和LGPL