【TLV】非递归TLV数据解析
#include <stdio.h> #define X_LEN_OF_TAG_MAX ( 2 )
#define X_LEN_OF_LEN_MAX ( 2 ) struct st_tlv_t {
unsigned int TAG;
unsigned char isCustructed;
unsigned int valLen;
unsigned char *pVal; }; static int skipZeroBytes( unsigned char **pcur, unsigned char *end )
{
while( **pcur == && (*pcur < end) )
(*pcur)++; if( *pcur < end )
return ; return ;
} static int parseTag( unsigned char **pcur, unsigned char *end, struct st_tlv_t *tlv )
{
unsigned char *pp;
int lenOfTag;
int i; if( *pcur >= end )
return ; pp = *pcur; lenOfTag = ;
if( (*pp++ & 0x1f) == 0x1f )
{
do {
if( pp >= end )
return ; lenOfTag++;
} while( (*pp++) & 0x80 );
}
if( lenOfTag > X_LEN_OF_TAG_MAX )
{
return ;
} tlv->isCustructed = ( **pcur & ( << ) ) ? : ; tlv->TAG = ;
for( i = ; i < lenOfTag; i++ )
{
tlv->TAG <<= ;
tlv->TAG |= *(*pcur + i );
} (*pcur) += lenOfTag;
//printf("tlv->TAG:%x\r\n", tlv->TAG);
return ;
} static int parseLength( unsigned char **pcur, unsigned char *end, struct st_tlv_t *tlv )
{
unsigned char *pp;
int lenOfLen;
int i; if( *pcur >= end || **pcur == )
return ; pp = *pcur; if( *pp & 0x80 )
{
lenOfLen = *pp & 0x7F;
if( pp + lenOfLen >= end )
return ;
if( lenOfLen > X_LEN_OF_LEN_MAX )
return ;
pp++;
tlv->valLen = ;
for( i = ; i < lenOfLen; i++ )
{
tlv->valLen <<= ;
tlv->valLen |= *(pp + i );
}
(*pcur) += (lenOfLen+);
}
else
{
tlv->valLen = **pcur;
(*pcur)++;
}
//printf("tlv->valLen:%d\r\n", tlv->valLen);
return ;
} static int parseValue( unsigned char **pcur, unsigned char *end, struct st_tlv_t *tlv )
{
if( (*pcur + tlv->valLen) > end )
return ; tlv->pVal = ( unsigned char *)(*pcur); return ;
} int parseTlv( unsigned char *buffer, int length, struct st_tlv_t *tlv )
{
unsigned char *cur;
unsigned char *end; cur = buffer;
end = buffer + length; if( !skipZeroBytes( &cur, end ) )
return ; if( !parseTag( &cur, end, tlv ) )
return ; if( !parseLength( &cur, end, tlv ) )
return ; if( !parseValue( &cur, end, tlv ) )
return ; return ;
} int printTlv( struct st_tlv_t *tlv )
{
int i;
printf("\r\n[%x] len:%d\r\n", tlv->TAG, tlv->valLen);
for( i = ; i < tlv->valLen; i++ )
printf("%02x", tlv->pVal[i]);
printf("\r\n"); return ;
} int parseTlvXXX( unsigned char *buffer, int length, int reverse )
{
unsigned char *cur;
unsigned char *end;
struct st_tlv_t tlv; cur = buffer;
end = buffer + length; while( cur < end )
{
if( !parseTlv( cur, end-cur, &tlv ) )
return ; printTlv( &tlv ); // 如果是复合型的TAG,则进入复合TAG内部继续分析
if( tlv.isCustructed && reverse )
{
cur = tlv.pVal;
}
else // 如果是简单型的TAG,则分析下一个TAG
{
cur = tlv.pVal + tlv.valLen;
}
} if( cur > end )
return ; return ;
} int main( void )
{
int ret; unsigned char tlv_buf0[] = {
0x70,0x28,0x61,0x26,0x4f,0x07,0xa0,0x00,
0x00,0x03,0x33,0x01,0x01,0x50,0x0b,0x50,
0x42,0x4f,0x43,0x20,0x43,0x72,0x65,0x64,
0x69,0x74,0x87,0x01,0x01,0x9f,0x12,0x0a,
0x50,0x42,0x4f,0x43,0x20,0x44,0x45,0x42,
0x49,0x54,0x90,0x00
};
unsigned char tlv_buf1[] = {
0x00,0x00,0x00,
0x70,0x81,0x83,0x90,0x81,0x80,0x25,0x3c,
0x3c,0x1f,0xd9,0x92,0x8d,0x88,0x21,0x11,
0xa6,0xac,0x4c,0xa2,0x07,0xdf,0x93,0x10,
0x64,0x23,0x95,0xea,0x09,0x7b,0x3c,0xb1,
0x6d,0x51,0x76,0x53,0x35,0x38,0x03,0xc2,
0xc1,0x03,0x3e,0x4a,0xac,0xb9,0x73,0x5d,
0x2e,0x69,0xca,0x49,0x8f,0xeb,0x4c,0xc0,
0xae,0xe1,0xff,0xc7,0xf5,0x44,0x83,0x09,
0x3a,0x30,0xcc,0xbf,0x6b,0x20,0x11,0xd6,
0x09,0xe5,0x2f,0xd7,0x87,0x76,0xb6,0x6b,
0x6d,0x86,0x95,0xcb,0xc0,0x46,0x21,0x6b,
0xf8,0x1c,0x52,0xd5,0xc2,0xf9,0x47,0xde,
0xe3,0xad,0xd7,0x20,0x9a,0xb3,0x27,0xf2,
0x9c,0x10,0x6b,0xfa,0x0e,0x29,0x1d,0x9d,
0xab,0x00,0x91,0x06,0xf4,0x89,0xba,0x59,
0x43,0x6d,0xa9,0x46,0x75,0xdf,0x9d,0x31,
0xdc,0xaf,0xbd,0x6a,0xbe,0x20,
};
unsigned char tlv_buf2[] = {
0x6f,0x24,0x84,0x0e,0x31,0x50,0x41,0x59,
0x2e,0x53,0x59,0x53,0x2e,0x44,0x44,0x46,
0x30,0x31,0xa5,0x12,0x88,0x01,0x01,0x5f,
0x2d,0x08,0x7a,0x68,0x65,0x6e,0x66,0x72,
0x64,0x65,0x9f,0x11,0x01,0x01
}; ret = parseTlvXXX( tlv_buf0, sizeof(tlv_buf0), );
printf("0-parseTlvXX: %d\r\n", ret); ret = parseTlvXXX( tlv_buf1, sizeof(tlv_buf1), );
printf("1-parseTlvXX: %d\r\n", ret); ret = parseTlvXXX( tlv_buf2, sizeof(tlv_buf2), );
printf("2-parseTlvXX: %d\r\n", ret); return ;
}
【TLV】非递归TLV数据解析的更多相关文章
- C语言递归,非递归实现翻转链表
翻转链表作为,链表的常用操作,也是面试常遇到的. 分析非递归分析: 非递归用的小技巧比较多,很容易出错. 递归分析比较简单,在代码里面 代码: #include<stdio.h> #inc ...
- iOS - JSON 数据解析
iOS - JSON 数据解析 前言 NS_CLASS_AVAILABLE(10_7, 5_0) @interface NSJSONSerialization : NSObject @availab ...
- python爬虫的页面数据解析和提取/xpath/bs4/jsonpath/正则(1)
一.数据类型及解析方式 一般来讲对我们而言,需要抓取的是某个网站或者某个应用的内容,提取有用的价值.内容一般分为两部分,非结构化的数据 和 结构化的数据. 非结构化数据:先有数据,再有结构, 结构化数 ...
- cJONS序列化工具解读二(数据解析)
cJSON数据解析 关于数据解析部分,其实这个解析就是个自动机,通过递归或者解析栈进行实现数据的解析 /* Utility to jump whitespace and cr/lf *///用于跳过a ...
- 通读AFN①--从创建manager到数据解析完毕
流程梳理 今天开始会写几篇关于AFN源码解读的一些Blog,首先要梳理一下AFN的整体结构(主要是讨论2.x版本的Session访问模块): 我们先看看我们最常用的一段代码: AFHTTPSessio ...
- 非递归创建二叉树( C++队列 )
非递归按照 层序 创建二叉树,利用 队列(即可先进先出特点)存放已访问的结点元素的地址. 初始化:front=rear= -1: 每储存一个结点元素 rear+1 ,利用 rear%2==0 来使 f ...
- 排序算法练习--JAVA(插入、直接选择、冒泡、快速排序、非递归快速排序)
排序算法是数据结构中的经典算法知识点,也是笔试面试中经常考察的问题,平常学的不扎实笔试时候容易出洋相,回来恶补,尤其是碰到递归很可能被问到怎么用非递归实现... package sort; impor ...
- 先贴上代码:Random快排,快排的非递归实现
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为主元,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序.值得注意的是, ...
- 利用Aspose.Cell控件导入Excel非强类型的数据
导入Excel的操作是非常常见的操作,可以使用Aspose.Cell.APOI.MyXls.OLEDB.Excel VBA等操作Excel文件,从而实现数据的导入,在导入数据的时候,如果是强类型的数据 ...
随机推荐
- String字符串的常用方法
1.substr():可在字符串中抽取从 start 下标开始的指定数目的字符. stringObject.substr(start,length) start:必需.要抽取的子串的起始下标.必须是数 ...
- AutoLayout的坑
本文投稿文章,作者:MangoMade(简书) AutoLayout非常强大也非常易用,可读性也很强,加上各种第三方AutoLayout库,让你布起局来犹如绷掉链子的狗!根本停不下来!以前的 1 la ...
- 静态代码扫描之阿里java代码规范IDEA插件
前言 2017年2月9日,首次公布<阿里巴巴Java开发手册>; 2017年9月25日,阿里巴巴集团发布了<阿里巴巴Java开发手册>PDF终极版; 2017年10月14日,在 ...
- 安装cmake 和 opencv 4.0.0
1.安装cmake3.5.1或更新的版本 安装gcc-c++:sudo apt-get install build-essential (或者直接执行这两条命令sudo apt-get install ...
- linux常用命令 awk命令
awk命令 awk [选项] '条件1{动作1} 条件2{动作2}...' 文件名 条件(Pattern) *) 一般使用关系表达式作为条件 *) x>10 判断变量x是否大于10 *) x&g ...
- ECharts柱状图
首先我们要先去Echarts 官网 根据自己需要的版本进行下载下载 下载完成后,我们在项目中引入echarts 随后创建容器来存放我们要添加的柱状图 容器创建完毕我们需要在js中设置他的属性和值 此配 ...
- Vue源码之----为什么Vue中Array的pop,push等方法可以reactive,而Array[0]='a'这样的方法不会reactive?
这就要从reactive开始讲起了,粗略的说,js的操作能引起页面上显示的改变,是因为该操作引起了组件的重新渲染,渲染会生成新的虚拟节点,新节点和旧节点会对比,操作浏览器的node进行改变. vue实 ...
- JS 中的对象
对象就是一个由属性构成的无序列合集. var myObj = { name: ‘suki’, age: 21, interests: [‘guitar’, ‘tennis’] }; 属性是没有顺序的, ...
- python之django基础
看了不是同一期的视频,发现9期老师线性引入的方式,讲得django更加易于理解掌握. 抱歉的是,笔记没有整理就发上来了.希望看到的人不要被我带偏. 1. 新建Django项目 命令行创建: djang ...
- 2017-9-24模拟赛T1 个人卫生综合征(school.*)
题目 每天 BBS 都要从家里经过城市中的一段路到学校刷五三.城市中一共有 n 个路口和 m 条双向道路,每条双向道路都连接着两个路口 a i .b i 且有一定的时间花费 v i .BBS家编号为 ...