好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

项目管理理论与实践系列文章索引

项目管理理论与实践系列文章索引

项目管理理论与实践(1)——企业项目管理介绍

项目管理理论与实践(2)——软件需求分析

项目管理理论与实践(3)——如何进行有效的项目管理

项目管理理论与实践(4)——UML应用(上)

项目管理理论与实践(5)——UML应用(下)

项目管理理论与实践(6)——利用Excel制作项目文档的设计技巧

项目管理理论与实践(7)——软件开发报价的计算方法

待续

作者: Leepy

 

邮箱:sunleepy(AT)gmail.com

 

出处: http://liping13599168.cnblogs.com/  

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

金融系统中PBOC/EMV的TLV的算法实现(含C++/C#)

      TLV即Tag-Length-Value,常在IC卡与POS终端设备中通过这样的一个应用通信协议进行数据交换。在金融系统以及认证中,PBOC以及 EMV的认证规范文档上面也有对TLV做了一些说明,由于认证规范都是英文文档,所以有些人可能不易于理解。首先我先介绍下什么是TLV,TLV的用途是 什么,以及如何实现它的打包解包算法。

      金融系统中的TLV是BER-TLV编码的一个特例编码规范,而BER-TLV是ISO定义中的规范。在TLV的定义中,可以知道它包括三个域,分别为:标签域(Tag),长度域(Length),内容域(Value)。 这里的长度域的值实际上就是内容域的长度 。

      其实,在BER编码的方式有两种情况,一种是确定长度的方式,一种是不确定长度的方式,而金融TLV选择了确定长度的方式,这样在设备之间的数据传输量上就可以减少。

Tag域说明:

      先来看下TLV的Tag是如何编码的,先看下图:

这张图说明了Tag域第一个字节的编码格式。其中b8-b1代表1个字节中的8个位。

其中b8,b7代表数据的类别。根据2个位的组合,有四种类别:通用类别,应用类别,上下文语境类别,专用类别。这个主要用于在于终端设备交互的时候,确定数据处理的类型。

b6代表的是数据元结构,也就是说它是属于简单数据元结构,还是属于结构(复合)数据元结构。当b6为1的时候,就需要后续的字节进行扩展。也就是说复合的TLV中,value域里也包含一个或多个TLV,这个稍后接着介绍。

当b5-b1代表串行号,当5个位都为1时,需要将tag域扩展到下一个字节中,也就是Tag占2个字节;而当5个位都不全为1时,该Tag域就只占1个字节。

      现在,看下b5-b1:11111的情况:

      从图中我们看到BER-TLV编码中,当b8为1时,Tag还需要有后续字节,直到b8为0为止。从EMV文档中的说明,Tag最多只占用2个字节,所以这样就相对比较简单一些了。当b8为0时,该Tag域结束,总共就占用2个字节。

Length域说明:

      在文档中没有图片叙述,我自绘一个:

当b8为0时,该字节的b7-b1作为value域的长度;当b8为1时,b7-b1作为后续字节的长度,也就是说,例如有这样一个 值:10000011,代表后续还有3个字节作为value域的长度(本字节不算,本字节变为作为一个Length的索引)。3个字节代表value的长 度,意味着什么呢,意味着内容的长度当需要很大的时候,字节的位数就会跟着越高,3个字节就代表最大可以有256*256*256的长度。

Value域说明:

      也是分成两种情况考虑,就是前面说到的Tag分成两个数据元结构,一种是简单数据元结构,一种是复合数据元架构:

      先来看看简单数据元结构:

     

Tag就是Tag,没有子标签Tag,基本结构就是T-L-V。

      再看下符合数据元结构:

后面的Value说明:Primitive or constructed BER-TLV data object number,包含一个简单数据元结构或者也可以是一个符合数据元结构。这样可以看出,算法中必须要实现Tag的嵌套功能,递归算法不可少。

算法实现:

      根据以上的说明现在来实现它的打包解包的算法(打包的目的是将一个从终端上发的请求数据——字节数组,构造成一系列的TLV结构实体;解包的目的刚好相反,就是将TLV结构实体解析成字节数组,然后通过IC卡发送到终端上)。

      首先定义一个TLV结构实体:

1 // TLV结构体

2 struct TLVEntity {

3      unsigned char * Tag;         //标记

4      unsigned char * Length;      //数据长度

5      unsigned char * Value;       //数据

6      unsigned int TagSize;       //标记占用字节数

7      unsigned int LengthSize;    //数据长度占用字节数

8      TLVEntity* Sub_TLVEntity;   //子嵌套TLV实体

9 };

其 中TagSize代表Tag字段的字节长度,LengthSize代表Length的字节长度,这里的Length记住要使用char*,由于前面说 过,Length可能包含多个字节,通过多个字节确定Value域的长度,Sub_TLVEntity作为子嵌套的TLV结构体。

      定义一个TLVPackage的打包类:

TLVPackage.h:

01 // TLV打包类

02 class TLVPackage

03 {

04 public :

05      TLVPackage();

06      virtual ~TLVPackage();

07      //构造TLV实体

08      static void Construct(unsigned char * buffer, unsigned int bufferLength, TLVEntity* tlvEntity, unsigned int & entityLength, unsigned int status=0);

09      //解析TLV字节数组

10      static void Parse(TLVEntity* tlvEntity, unsigned int entityLength, unsigned char * buffer, unsigned int & bufferLength);

11 };

具体方法实现:

001 // 构造TLV

002 void TLVPackage:: Construct(

003      unsigned char * buffer,

004      unsigned int bufferLength,

005      TLVEntity* tlvEntity,

006      unsigned int & entityLength,

007      unsigned int status

008      )

009 {

010      int currentTLVIndex = 0;

011      int currentIndex = 0;

012      int currentStatus = 'T' ; //状态字符

013      unsigned long valueSize = 0;

014  

015      while (currentIndex < bufferLength)

016      {

017          switch (currentStatus)

018          {

019          case 'T' :

020              valueSize = 0;

021              //判断是否单一结构

022              if ((status == 1 && buffer[currentIndex] & 0x20) != 0x20)

023              {

024                  tlvEntity[currentTLVIndex].Sub_TLVEntity = NULL; //单一结构时将子Tag置空

025                  //判断是否多字节Tag

026                  if ((buffer[currentIndex] & 0x1f) == 0x1f)

027                  {

028                      int endTagIndex = currentIndex;

029                      while ((buffer[++endTagIndex] & 0x80) == 0x80); //判断第二个字节的最高位是否为1

030                      int tagSize = endTagIndex - currentIndex + 1; //计算Tag包含多少字节

031  

032                      tlvEntity[currentTLVIndex].Tag = new unsigned char [tagSize];

033                      memcpy (tlvEntity[currentTLVIndex].Tag, buffer + currentIndex, tagSize);

034                      tlvEntity[currentTLVIndex].Tag[tagSize] = 0;

035  

036                      tlvEntity[currentTLVIndex].TagSize = tagSize;

037  

038                      currentIndex += tagSize;

039                  }

040                  else

041                  {

042                      tlvEntity[currentTLVIndex].Tag = new unsigned char [1];

043                      memcpy (tlvEntity[currentTLVIndex].Tag, buffer + currentIndex, 1);

044                      tlvEntity[currentTLVIndex].Tag[1] = 0;

045  

046                      tlvEntity[currentTLVIndex].TagSize = 1;

047  

048                      currentIndex += 1;

049                  }

050              }

051              else

052              {

053                  //判断是否多字节Tag

054                  if ((buffer[currentIndex] & 0x1f) == 0x1f)

055                  {

056                      int endTagIndex = currentIndex;

057                      while ((buffer[++endTagIndex] & 0x80) == 0x80); //判断第二个字节的最高位是否为1

058                      int tagSize = endTagIndex - currentIndex + 1; //计算Tag包含多少字节

059  

060                      tlvEntity[currentTLVIndex].Tag = new unsigned char [tagSize];

061                      memcpy (tlvEntity[currentTLVIndex].Tag, buffer + currentIndex, tagSize);

062                      tlvEntity[currentTLVIndex].Tag[tagSize] = 0;

063  

064                      tlvEntity[currentTLVIndex].TagSize = tagSize;

065  

066                      currentIndex += tagSize;

067                  }

068                  else

069                  {

070                      tlvEntity[currentTLVIndex].Tag = new unsigned char [1];

071                      memcpy (tlvEntity[currentTLVIndex].Tag, buffer + currentIndex, 1);

072                      tlvEntity[currentTLVIndex].Tag[1] = 0;

073  

074                      tlvEntity[currentTLVIndex].TagSize = 1;

075  

076                      currentIndex += 1;             

077                  }

078  

079                  //分析SubTag

080                  int subLength = 0; 

081                   

082                  unsigned char * temp;

083                  if ((buffer[currentIndex] & 0x80) == 0x80)

084                  {

085                      for ( int index = 0; index < 2; index++)

086                      {

087                          subLength += buffer[currentIndex + 1 + index] << (index * 8); //计算Length域的长度

088                      }

089  

090                      temp = new unsigned char [subLength];

091  

092                      memcpy (temp, buffer + currentIndex + 3, subLength);

093                  }

094                  else

095                  {

096                      subLength = buffer[currentIndex];

097  

098                      temp = new unsigned char [subLength];

099  

100                      memcpy (temp, buffer + currentIndex + 1, subLength);

101                  }

102                  temp[subLength] = 0;

103                   

104                  //memcpy(temp, buffer + currentIndex + 1, subLength);

105                  unsigned int oLength;

106                  tlvEntity[currentTLVIndex].Sub_TLVEntity = new TLVEntity[1];

107                  Construct(temp, subLength, tlvEntity[currentTLVIndex].Sub_TLVEntity, oLength);

108              }

109  

110              currentStatus = 'L' ;

111              break ;

112          case 'L' :      

113              //判断长度字节的最高位是否为1,如果为1,则该字节为长度扩展字节,由下一个字节开始决定长度

114              if ((buffer[currentIndex] & 0x80) != 0x80)

115              {

116                  tlvEntity[currentTLVIndex].Length = new unsigned char [1];

117                  memcpy (tlvEntity[currentTLVIndex].Length, buffer + currentIndex, 1);

118                  tlvEntity[currentTLVIndex].Length[1] = 0;

119                  tlvEntity[currentTLVIndex].LengthSize = 1;

120  

121                  valueSize = tlvEntity[currentTLVIndex].Length[0];

122  

123                  currentIndex += 1;

124              }

125              else

126              {

127                  //为1的情况

128  

129                  unsigned int lengthSize = buffer[currentIndex] & 0x7f;

130                   

131                  currentIndex += 1; //从下一个字节开始算Length域

132  

133                  for ( int index = 0; index < lengthSize; index++)

134                  {

135                      valueSize += buffer[currentIndex + index] << (index * 8); //计算Length域的长度

136                  }

137  

138                  tlvEntity[currentTLVIndex].Length = new unsigned char [lengthSize];

139                  memcpy (tlvEntity[currentTLVIndex].Length, buffer + currentIndex, lengthSize);

140                  tlvEntity[currentTLVIndex].Length[lengthSize] = 0;

141  

142                  tlvEntity[currentTLVIndex].LengthSize = lengthSize;

143  

144                  currentIndex += lengthSize;

145              }

146  

147              currentStatus = 'V' ;

148              break ;

149          case 'V' :

150              tlvEntity[currentTLVIndex].Value = new unsigned char [valueSize];

151              memcpy (tlvEntity[currentTLVIndex].Value, buffer + currentIndex, valueSize);

152              tlvEntity[currentTLVIndex].Value[valueSize] = 0;

153  

154              currentIndex += valueSize;

155               

156              //进入下一个TLV构造循环

157              currentTLVIndex += 1;

158  

159              currentStatus = 'T' ;

160              break ;

161          default :

162              return ;

163          }

164      }

165  

166      entityLength = currentTLVIndex;

167 }

168  

169 // 解析TLV

170 void TLVPackage::Parse(

171      TLVEntity* tlvEntity,

172      unsigned int entityLength,

173      unsigned char * buffer,

174      unsigned int & bufferLength

175      )

176 {

177      int currentIndex = 0;

178      int currentTLVIndex = 0;

179      unsigned long valueSize = 0;

180  

181      while (currentTLVIndex < entityLength)

182      {

183          valueSize = 0;

184          TLVEntity entity = tlvEntity[currentTLVIndex];

185           

186          memcpy (buffer + currentIndex, entity.Tag, entity.TagSize);  //解析Tag

187          currentIndex += entity.TagSize;

188  

189          for ( int index = 0; index < entity.LengthSize; index++)

190          {

191              valueSize += entity.Length[index] << (index * 8); //计算Length域的长度

192          }

193          if (valueSize > 127)

194          {

195              buffer[currentIndex] = 0x80 | entity.LengthSize;

196              currentIndex += 1;

197          }

198           

199          memcpy (buffer + currentIndex, entity.Length, entity.LengthSize);    //解析Length

200          currentIndex += entity.LengthSize;

201          //判断是否包含子嵌套TLV

202          if (entity.Sub_TLVEntity == NULL)

203          {

204              memcpy (buffer + currentIndex, entity.Value, valueSize); //解析Value

205              currentIndex += valueSize;

206          }

207          else

208          {

209              unsigned int oLength;

210              Parse(entity.Sub_TLVEntity, 1, buffer + currentIndex, oLength); //解析子嵌套TLV

211              currentIndex += oLength;

212          }

213  

214          currentTLVIndex++;

215      }

216      buffer[currentIndex] = 0;

217      bufferLength = currentIndex;

218 }

然后写测试程序:

01 // 上发测试数据

02 unsigned char requestBuf[] = {

03          0x9F, 0x1C, 0x12, 0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32, 0x30, 0x34, 0x30, 0x34,

04          0x32, 0x37, 0x31, 0x38, 0x9F, 0x62, 0x01, 0x01, 0x57, 0x12, 0x62, 0x22, 0x89, 0x00, 0x00, 0x02, 0x91,

05          0x01, 0xD0, 0x90, 0x32, 0x01, 0x02, 0x47, 0x17, 0x13, 0x00, 0x0F, 0x5F, 0x20, 0x0A, 0x48, 0x55, 0x47,

06          0x55, 0x4F, 0x20, 0x4D, 0x49, 0x4E, 0x47, 0x9F, 0x1F, 0x3C, 0x25, 0x39, 0x39, 0x36, 0x32, 0x32, 0x32,

07          0x38, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x39, 0x31, 0x30, 0x31, 0x5E, 0x47, 0x55, 0x4F, 0x20,

08          0x4D, 0x49, 0x4E, 0x47, 0x2F, 0x48, 0x55, 0x5E, 0x30, 0x39, 0x30, 0x33, 0x32, 0x30, 0x31, 0x30, 0x32,

09          0x34, 0x37, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x38, 0x39, 0x30,

10          0x30, 0x3F

11 };

12  

13      TLVEntity tlvEntity[TLV_MAX_LENGTH];

14      unsigned int tlv_count;

15      //构造TLV

16      TLVPackage::Construct(requestBuf, sizeof (requestBuf), tlvEntity, tlv_count);

17  

18      unsigned char parseBuf[1024];

19      unsigned int buf_count;

20      //解析TLV

21      TLVPackage::Parse(tlvEntity, tlv_count, parseBuf, buf_count);

22  

23      if ( strncmp (( char *)parseBuf, ( char *)requestBuf, sizeof (requestBuf)) == 0)

24      {

25          AfxMessageBox( "TRUE" );

26      }

27      else

28      {

29          AfxMessageBox( "FALSE" );

30      }

最后测试结果中,可以得到最后将弹出“TRUE”的对话框。证明构造TLV得到的TLVEntity,再对这个实体进行解析,可以的到解析后的字节数组,最后通过strncmp的方法比较判断,是否原始字节数组和解析后的字节数组是否一致。

另外, 为了方便C#程序员的使用,我对该C++程序重新改写了一下 ,得出的结果也是一样的。

TLVEntity.cs

01 /// <summary>

02      /// TLV实体

03      /// </summary>

04      public class TLVEntity

05      {

06          /// <summary>

07          /// 标记

08          /// </summary>

09          public byte [] Tag { get ; set ; }

10  

11          /// <summary>

12          /// 数据长度

13          /// </summary>

14          public byte [] Length { get ; set ; }

15  

16          /// <summary>

17          /// 数据

18          /// </summary>

19          public byte [] Value { get ; set ; }

20  

21          /// <summary>

22          /// 标记占用字节数

23          /// </summary>

24          public int TagSize { get ; set ; }

25  

26          /// <summary>

27          /// 数据长度占用字节数

28          /// </summary>

29          public int LengthSize { get ; set ; }

30  

31          /// <summary>

32          /// 子嵌套TLV实体

33          /// </summary>

34          public TLVEntity Sub_TLVEntity { get ; set ; }

35      }

以及TLVPackage.cs

001 /// <summary>

002      /// TLV打包类

003      /// </summary>

004      public class TLVPackage

005      {

006          /// <summary>

007          /// 构造TLV

008          /// </summary>

009          /// <param name="buffer">

010          public static List<tlventity> Construct( byte [] buffer)

011          {

012              List<tlventity> list = new List<tlventity>();

013              int currentTLVIndex = 0;

014              int currentIndex = 0;

015              int currentStatus = 'T' ; //状态字符

016              int valueSize = 0;

017  

018              TLVEntity tlvEntity = null ;

019  

020              while (currentIndex < buffer.Length)

021              {

022                  switch (currentStatus)

023                  {

024                      case 'T' :

025                          tlvEntity = new TLVEntity();

026                          valueSize = 0;

027                          //判断是否单一结构

028                          if ((buffer[currentIndex] & 0x20) != 0x20)

029                          {

030                              tlvEntity.Sub_TLVEntity = null ; //单一结构时将子Tag置空【】

031                              //判断是否多字节Tag

032                              if ((buffer[currentIndex] & 0x1f) == 0x1f)

033                              {

034                                  int endTagIndex = currentIndex;

035                                  while ((buffer[++endTagIndex] & 0x80) == 0x80) ; //判断第二个字节的最高位是否为1

036                                  int tagSize = endTagIndex - currentIndex + 1; //计算Tag包含多少字节

037  

038                                  tlvEntity.Tag = new byte [tagSize];

039                                  Array.Copy(buffer, currentIndex, tlvEntity.Tag, 0, tagSize);

040  

041                                  tlvEntity.TagSize = tagSize;

042  

043                                  currentIndex += tagSize;

044                              }

045                              else

046                              {

047                                  tlvEntity.Tag = new byte [1];

048                                  Array.Copy(buffer, currentIndex, tlvEntity.Tag, 0, 1);

049  

050                                  tlvEntity.TagSize = 1;

051  

052                                  currentIndex += 1;

053                              }

054                          }

055                          else

056                          {

057                              //判断是否多字节Tag

058                              if ((buffer[currentIndex] & 0x1f) == 0x1f)

059                              {

060                                  int endTagIndex = currentIndex;

061                                  while ((buffer[++endTagIndex] & 0x80) == 0x80) ; //判断第二个字节的最高位是否为1

062                                  int tagSize = endTagIndex - currentIndex + 1; //计算Tag包含多少字节

063  

064                                  tlvEntity.Tag = new byte [tagSize];

065                                  Array.Copy(buffer, currentIndex, tlvEntity.Tag, 0, tagSize);

066  

067                                  tlvEntity.TagSize = tagSize;

068  

069                                  currentIndex += tagSize;

070                              }

071                              else

072                              {

073                                  tlvEntity.Tag = new byte [1];

074                                  Array.Copy(buffer, currentIndex, tlvEntity.Tag, 0, 1);

075  

076                                  tlvEntity.TagSize = 1;

077  

078                                  currentIndex += 1;

079                              }

080  

081                              //分析SubTag

082                              int subLength = 0;

083  

084                              byte [] temp;

085                              if ((buffer[currentIndex] & 0x80) == 0x80)

086                              {

087                                  for ( int index = 0; index < 2; index++)

088                                  {

089                                      subLength += buffer[currentIndex + 1 + index] << (index * 8); //计算Length域的长度

090                                  }

091  

092                                  temp = new byte [subLength];

093  

094                                  Array.Copy(buffer, currentIndex + 3, temp, 0, subLength);

095                              }

096                              else

097                              {

098                                  subLength = buffer[currentIndex];

099  

100                                  temp = new byte [subLength];

101  

102                                  Array.Copy(buffer, currentIndex + 1, temp, 0, subLength);

103                              }

104  

105                              int oLength;

106                              tlvEntity.Sub_TLVEntity = new TLVEntity();

107                              List<tlventity> tempList = Construct(temp);

108                              tlvEntity.Sub_TLVEntity = tempList[0];

109                          }

110  

111                          currentStatus = 'L' ;

112                          break ;

113                      case 'L' :

114                          //判断长度字节的最高位是否为1,如果为1,则该字节为长度扩展字节,由下一个字节开始决定长度

115                          if ((buffer[currentIndex] & 0x80) != 0x80)

116                          {

117                              tlvEntity.Length = new byte [1];

118                              Array.Copy(buffer, currentIndex, tlvEntity.Length, 0, 1);

119  

120                              tlvEntity.LengthSize = 1;

121  

122                              valueSize = tlvEntity.Length[0];

123                              currentIndex += 1;

124                          }

125                          else

126                          {

127                              //为1的情况

128  

129                              int lengthSize = buffer[currentIndex] & 0x7f;

130  

131                              currentIndex += 1; //从下一个字节开始算Length域

132  

133                              for ( int index = 0; index < lengthSize; index++)

134                              {

135                                  valueSize += buffer[currentIndex + index] << (index * 8); //计算Length域的长度

136                              }

137  

138                              tlvEntity.Length = new byte [lengthSize];

139                              Array.Copy(buffer, currentIndex, tlvEntity.Length, 0, lengthSize);

140  

141                              tlvEntity.LengthSize = lengthSize;

142  

143                              currentIndex += lengthSize;

144                          }

145  

146                          currentStatus = 'V' ;

147                          break ;

148                      case 'V' :

149                          tlvEntity.Value = new byte [valueSize];

150                          Array.Copy(buffer, currentIndex, tlvEntity.Value, 0, valueSize);

151  

152                          currentIndex += valueSize;

153  

154                          //进入下一个TLV构造循环

155                          list.Add(tlvEntity);

156  

157                          currentStatus = 'T' ;

158                          break ;

159                      default :

160                          return new List<tlventity>();

161                  }

162              }

163  

164              return list;

165          }

166  

167          /// <summary>

168          /// 解析TLV

169          /// </summary>

170          /// <param name="list">

171          /// <returns></returns>

172          public static byte [] Parse(List<tlventity> list)

173          {

174              byte [] buffer = new byte [4096];

175              int currentIndex = 0;

176              int currentTLVIndex = 0;

177              int valueSize = 0;

178  

179              while (currentTLVIndex < list.Count())

180              {

181                  valueSize = 0;

182                  TLVEntity entity = list[currentTLVIndex];

183  

184                  Array.Copy(entity.Tag, 0, buffer, currentIndex, entity.TagSize);    //解析Tag

185  

186                  currentIndex += entity.TagSize;

187  

188                  for ( int index = 0; index < entity.LengthSize; index++)

189                  {

190                      valueSize += entity.Length[index] << (index * 8); //计算Length域的长度

191                  }

192                  if (valueSize > 127)

193                  {

194                      buffer[currentIndex] = Convert.ToByte(0x80 | entity.LengthSize);

195                      currentIndex += 1;

196                  }

197  

198                  Array.Copy(entity.Length, 0, buffer, currentIndex, entity.LengthSize);  //解析Length

199  

200                  currentIndex += entity.LengthSize;

201                  //判断是否包含子嵌套TLV

202                  if (entity.Sub_TLVEntity == null )

203                  {

204                      Array.Copy(entity.Value, 0, buffer, currentIndex, valueSize);   //解析Value

205                      currentIndex += valueSize;

206                  }

207                  else

208                  {

209                      byte [] tempBuffer = Parse( new List<tlventity> { entity.Sub_TLVEntity });

210                      Array.Copy(tempBuffer, 0, buffer, currentIndex, tempBuffer.Length); //解析子嵌套TLV

211                      currentIndex += tempBuffer.Length;

212                  }

213  

214                  currentTLVIndex++;

215              }

216  

217              byte [] resultBuffer = new byte [currentIndex];

218              Array.Copy(buffer, 0, resultBuffer, 0, currentIndex);

219  

220              return resultBuffer;

221          }

222      }</tlventity></tlventity></tlventity></tlventity></tlventity></tlventity></tlventity>

接着,写测试程序:

01 static byte [] requestBuffer =

02          {

03              0x9F, 0x1C, 0x82, 0x2C, 0x01,

04              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

05              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

06              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

07              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

08              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

09              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

10              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

11              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

12              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

13              0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,0x33, 0x33, 0x30, 0x32, 0x32, 0x37, 0x31, 0x39, 0x36, 0x32,

14              0x71, 0x07, 0x9f, 0x19, 0x04, 0x11, 0x22, 0x33, 0x44

15          };

16  

17          static void Main( string [] args)

18          {

19              Console.WriteLine( "待组装的数据包:" );

20              requestBuffer.ToList().ForEach(o => { Console.Write( "{0}," , "0x" + o.ToString( "X" )); });

21  

22              Console.WriteLine( "\r\n\r\n开始构造TLV" );

23              //构造TLV

24              List<tlventity> list = TLVPackage.Construct(requestBuffer);

25              Console.WriteLine( "\r\n构造结束!" );

26  

27              Console.WriteLine( "\r\n开始解析TLV" );

28              //解析TLV

29              byte [] responseBuffer = TLVPackage.Parse(list);

30              Console.WriteLine( "\r\n解析结束!" );

31  

32              Console.WriteLine( "\r\n解析结果:" );

33  

34              if (ByteEquals(requestBuffer, responseBuffer))

35              {

36                  Console.WriteLine( "Equal!" );

37              }

38              else

39              {

40                  Console.WriteLine( "Not Equal!" );

41              }

42  

43              Console.ReadKey();

44          }</tlventity>

运行结果:

总结

TLV在数据通信方面,其实运用得很广泛,在应用层数据通信中,如HTTP协议,HTML,XML语言本身定义了一些标签 (Body,Head,Script)对数据串行化,接收方再根据标签解析原始数据,通过浏览器展现出来。因此本质上也是属于TLV协议的设计模式。甚至 在传输层的TCP,UDP协议,你完全可以通过TLV实现自定义的应用协议。

附上C#源代码: TLVPackageDemo.rar

作者: Leepy

 

邮箱:sunleepy(AT)gmail.com

 

出处: http://liping13599168.cnblogs.com/  

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于项目管理理论与实践系列文章索引的详细内容...

  阅读:48次

上一篇: Thread类

下一篇:.Net调试技巧