TLV格式解析
TLV:TLV格式数据是指由Tag,Length,Value组成的数据。具体说明如下:
tag标签的属性为bit,由16进制表示,占1~2个字节长度。例如,“0x9F33”为一个占用两个字节 的tag标签。而“0x95”为一个占用一个字节的tag标签。若tag标签的第一个字节(注:字节排序方向为从左往右数,第一个字节即为最左边的字节。bit排序规则同理。)的后四个bit为“1111”,则说明该tag占两个字节,例如“0x9F33”;否则占一个字节,例“0x95”。
子域长度(即L本身)的属性也为bit,占1~3个字节长度。具体编码规则如下:
a) 当 L 字段最左边字节的最左 bit 位(即 bit8)为 0,表示该 L 字段占一个字节,它的后续 7个 bit 位(即 bit7~bit1)表示子域取值的长度,采用二进制数表示子域取值长度的十进制数。例如,某个域取值占 3 个字节,那么其子域取值长度表示为“00000011”。所以,若子域取值的长度在 1~127 字节之间,那么该 L 字段本身仅占一个字节。
b) 当 L 字段最左边字节的最左 bit 位(即 bit8)为 1,表示该 L 字段不止占一个字节,那么它到底占几个字节由该最左字节的后续 7 个 bit 位(即 bit7~bit1)的十进制取值表示。例如,若最左字节为 10000010,表示 L 字段除该字节外,后面还有两个字节。其后续字节的十进制
取值表示子域取值的长度。例如,若 L 字段为“1000 0001 1111 1111”,表示该子域取值占255 个字节。所以,若子域取值的长度在 127~255 字节之间,那么该 L 字段本身需占两个字节。
解析TLV步骤:
1、将TLV数据内容十六进制转为byte字节数组 byte[] aBuf
2、循环解析TLV结构内容,从第一个开始
(1) 解析tag字节长度
private int getTagBytesCount(byte[] aBuf, int aOffset) { //Tag 第一个字节的B1 到 B5 是否都为1 ,如果是,tag为2个字节 if((aBuf[aOffset] & 0x1F) == 0x1F) { // see subsequent bytes int len = 2; for(int i=aOffset+1; i<aOffset+10; i++) { if( (aBuf[i] & 0x80) != 0x80) { break; } len++; } return len; } else { return 1; } }
(2) 解析tag字节内容
通过 aBuf , 开始下标和tag长度获取tag字节内容
(3) 解析length长度
private int getLengthBytesCount(byte aBuf[], int aOffset) { int len = aBuf[aOffset] & 0xff; //最左边字节的最左 bit 位(即 bit8)为 1,表示该 L 字段不止占一个字节, //字节数由该最左字节的后续 7 个 bit 位(即 bit7~bit1)的十进制取值表示 if( (len & 0x80) == 0x80) { return 1 + (len & 0x7f); } else { return 1; } }
(4) 解析length字节内容(即value的长度)
private int getDataLength(byte[] aBuf, int aOffset) { int length = aBuf[aOffset] & 0xff; if((length & 0x80) == 0x80) { int numberOfBytes = length & 0x7f; if(numberOfBytes>3) { throw new IllegalStateException(String.format("At position %d the len is more then 3 [%d]", aOffset, numberOfBytes)); } length = 0; for(int i=aOffset+1; i<aOffset+1+numberOfBytes; i++) { length = length * 0x100 + (aBuf[i] & 0xff); } } return length; }
(5) 通过tag字节内容(B6位,0x20)判断数据类型(基本数据类型和结构数据类型)
(bytes[0] & 0x20) != 0
如果是基本数据类型,通过length长度直接解析value值;
如果是结构数据类型,通过(步骤2)解析length长度字节的内容,
本文来自博客园,作者:路易蓝,转载请注明原文链接:https://www.cnblogs.com/luyilan/p/13889326.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!