zoukankan      html  css  js  c++  java
  • TLV格式解析

    TLVTLV格式数据是指由TagLengthValue组成的数据。具体说明如下:

        tag标签的属性为bit,由16进制表示,占12个字节长度。例如,0x9F33”为一个占用两个字节 tag标签。而0x95”为一个占用一个字节的tag标签。若tag标签的第一个字节(注:字节排序方向为从左往右数,第一个字节即为最左边的字节。bit排序规则同理。)的后四个bit“1111”,则说明该tag占两个字节,例如0x9F33”;否则占一个字节,例0x95” 

     

    子域长度(即L本身)的属性也为bit,占13个字节长度。具体编码规则如下: 
               a)  L 字段最左边字节的最左 bit 位(即 bit8)为 0,表示该 L 字段占一个字节,它的后续 7bit 位(即 bit7bit1)表示子域取值的长度,采用二进制数表示子域取值长度的十进制数。例如,某个域取值占 3 个字节,那么其子域取值长度表示为“00000011”。所以,若子域取值的长度在 1127 字节之间,那么该 L 字段本身仅占一个字节。 
               b)  L 字段最左边字节的最左 bit 位(即 bit8)为 1,表示该 L 字段不止占一个字节,那么它到底占几个字节由该最左字节的后续 7 bit 位(即 bit7bit1)的十进制取值表示。例如,若最左字节为 10000010,表示 L 字段除该字节外,后面还有两个字节。其后续字节的十进制
    取值表示子域取值的长度。例如,若 L 字段为“1000 0001 1111 1111”,表示该子域取值占255 个字节。所以,若子域取值的长度在 127255 字节之间,那么该 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长度字节的内容,

  • 相关阅读:
    进程线程模型
    操作系统运行机制
    操作系统概论
    排序
    win32消息机制
    win32框架
    map
    deque & list
    vector内部实现2
    蓝桥杯 文化之旅 图论 待复习
  • 原文地址:https://www.cnblogs.com/luyilan/p/13889326.html
Copyright © 2011-2022 走看看