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長度字節的內容,

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM