ASN1 TLV三元组解析-荆轲

1.TLV

BER编码的一种,ASN1标准,全称Tag(标签),Length(长度),Value(值)。
IS-IS数据通信领域中,tlv三元组: tag-length-value(TLV)。T、L字段的长度往往固定(通常为1~4bytes),V字段长度可变。顾名思义,T字段表示报文类型,L字段表示报文长度、V字段往往用来存放报文的内容。

前面有讲,哎,来个法师,2金开个传送门,

ASN1 TLV三元组解析-荆轲_第1张图片

https://blog.csdn.net/qq_14945847/article/details/79369041

但是TLV格式怎么解析呢?

2.解析TLV

public class Tlv {
  
    /** 子域Tag标签 */  
    private String tag;  
  
    /** 子域取值的长度 */  
    private int length;  
  
    /** 子域取值 */  
    private String value;  
  
    public Tlv(String tag, int length, String value) {  
        this.length = length;  
        this.tag = tag;  
        this.value = value;  
    }  
  
    public String getTag() {  
        return tag;  
    }  
  
    public void setTag(String tag) {  
        this.tag = tag;  
    }  
  
    public int getLength() {  
        return length;  
    }  
  
    public void setLength(int length) {  
        this.length = length;  
    }  
  
    public String getValue() {  
        return value;  
    }  
  
    public void setValue(String value) {  
        this.value = value;  
    }  
  
    @Override  
    public String toString() {  
        return "tag=[" + this.tag + "]," + "length=[" + this.length + "]," + "value=[" + this.value + "]";  
    }  
}
/**
 * 将字符串转换为TLV对象 
 *  
 */  
public abstract class TlvUtils {  
  
    /** 
     * 将16进制字符串转换为TLV对象列表 
     * @param hexString 
     * @return 
     */  
    public static List builderTlvList(String hexString) {
        List tlvs = new ArrayList();
  
        int position = 0;  
        while (position != StringUtils.length(hexString)) {
            String _hexTag = getTag(hexString, position);  
            position += _hexTag.length();  
  
            LPositon l_position = getLengthAndPosition(hexString, position);  
            int _vl = l_position.get_vL();  
  
            position = l_position.get_position();  
  
            String _value = StringUtils.substring(hexString, position, position + _vl * 2);  
  
            position = position + _value.length();  
  
            tlvs.add(new Tlv(_hexTag, _vl, _value));  
        }  
        return tlvs;  
    }  
      
    /** 
     * 将16进制字符串转换为TLV对象MAP 
     * @param hexString 
     * @return 
     */  
    public static Map builderTlvMap(String hexString) {  
  
        Map tlvs = new HashMap();
  
        int position = 0;  
        while (position != hexString.length()) {  
            String _hexTag = getTag(hexString, position);  
              
            position += _hexTag.length();  
              
            LPositon l_position = getLengthAndPosition(hexString, position);  
              
            int _vl = l_position.get_vL();  
            position = l_position.get_position();  
            String _value = hexString.substring(position, position + _vl * 2);  
            position = position + _value.length();  
              
            tlvs.put(_hexTag, new Tlv(_hexTag, _vl, _value));  
        }  
        return tlvs;  
    }  
      
    /** 
     * 返回最后的Value的长度 
     *  
     * @param hexString 
     * @param position 
     * @return  
     */  
    private static LPositon getLengthAndPosition(String hexString, int position) {  
        String firstByteString = hexString.substring(position, position + 2);  
        int i = Integer.parseInt(firstByteString, 16);  
        String hexLength = "";  
  
        if (((i >>> 7) & 1) == 0) {  
            hexLength = hexString.substring(position, position + 2);  
            position = position + 2;  
        } else {  
            // 当最左侧的bit位为1的时候,取得后7bit的值,  
            int _L_Len = i & 127;  
            position = position + 2;  
            hexLength = hexString.substring(position, position + _L_Len * 2);  
            // position表示第一个字节,后面的表示有多少个字节来表示后面的Value值  
            position = position + _L_Len * 2;  
        }  
        return new LPositon(Integer.parseInt(hexLength, 16), position);  
  
    }  
  
    /** 
     * 取得子域Tag标签 
     *  
     * @param hexString 
     * @param position 
     * @return 
     */  
    private static String getTag(String hexString, int position) {  
        String firstByte = StringUtils.substring(hexString, position, position + 2);  
        int i = Integer.parseInt(firstByte, 16);  
        if ((i & 0x1f) == 0x1f) {  
            return hexString.substring(position, position + 4);  
  
        } else {  
            return hexString.substring(position, position + 2);  
        }  
    }  
}  

 LPosition.java


/**
 * @author liyongfei
 * @description: 
 * @date 2019/10/15 14:00
 */
public class LPositon{

    private int _vL;
    private int _position;

    public LPositon(int _vL, int _position) {
        this._vL = _vL;
        this._position = _position;
    }

    public int get_vL() {
        return _vL;
    }

    public void set_vL(int _vL) {
        this._vL = _vL;
    }

    public int get_position() {
        return _position;
    }

    public void set_position(int _position) {
        this._position = _position;
    }
}

3.测试

import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
 * @author liyongfei
 * @description:
 * @date 2019/10/17 14:19
 */
public class TlvUtilsTest {


    public static void main(String[] args) throws DecoderException {

        //1.2.86.11.7.7550307"
        String tlvString = "0C 12 E8 87 AA E5 AE 9A E4 B9 89 E6 89 A9 E5 B1 95 E5 9F 9F";
        System.out.println("转化前:"+tlvString);
        String hexString = StringUtils.remove(tlvString," ");
        List tlvList =  TlvUtils.builderTlvList(hexString);

        StringBuilder stringBuilder = new StringBuilder();
        System.out.println(JSON.toJSONString(tlvList));
        for (Tlv tlv :tlvList){
            stringBuilder.append(new String(Hex.decodeHex(tlv.getValue())));
        }

        System.out.println("转化后:"+stringBuilder.toString());
    }
}

4.测试结果

"0C 12 E8 87 AA E5 AE 9A E4 B9 89 E6 89 A9 E5 B1 95 E5 9F 9F"其实就是一个数字证书里面的一个值,其实内容就是“自定义扩展
域”

ASN1 TLV三元组解析-荆轲_第2张图片

 

你可能感兴趣的:(智能模块)