【问题标题】:How to parse TLV tag string in java如何在java中解析TLV标签字符串
【发布时间】:2018-03-12 17:07:07
【问题描述】:

我正在尝试解析 TLV 字符串:

24 00 35 E1 31 9F 08 02 38 30 9F 37 04 4A 66 6B 69 DF AE 05 01 41 9F 26 08 73 30 35 76 4F 6A 36 4E DF AE 06 0C 33 34 71 76 69 70 6B 4D 53 63 66 55 9F 36 02 00 01 90 00 7B

在这种情况下,9F08 是标签,后跟长度字段和数据。我能够使用我拥有的当前输入字符串获取所需的字段,但可能存在标签(“9F08”)也可能位于另一个字段的数据部分的情况。我对如何继续进行这件事感到困惑。

public void bleToPos(String hex) {
    sb=new StringBuilder();
    tlv=new TLVData();
    int noOfCharacters=0,src=0,dest=0;
    String epiolgue="",epligueData="";

    String [] hexArray=hex.split(" ");
    //Extract 1st 3 bytes and last 3 bytes. last 3 bytes should contain 90 00 otherwise not valid string
    epiolgue=hexArray[hexArray.length-3];
    epiolgue= epiolgue + hexArray[hexArray.length-2];
    epligueData = hexArray[hexArray.length-1];
    if(!epiolgue.equals("9000")) {
        System.out.println(" Not a valid tlv no need to process");
        return;
    }
    tlv.setEpilogue(epligueData);
    int arrayLength=hexArray.length;
    if(hexArray!=null && hexArray.length>0) {
        for(int i=0;i<hexArray.length;i++) {
            try {
                if(hexArray[i].equals("9F")) {
                    if((i+1)<arrayLength &&  hexArray[i+1].equals("08")) {
                        noOfCharacters= (char)Integer.parseInt(hexArray[i+2], 16);
                        src=i+3;
                        dest=src+noOfCharacters;
                        copyArrayElementsIntoString(src, dest, hexArray);
                        tlv.setVersion(sb.toString());
                        sb.setLength(0);
                    }
                    else if((i+1)<arrayLength && hexArray[i+1].equals("37")) {
                        noOfCharacters= (char)Integer.parseInt(hexArray[i+2], 16);
                        src=i+3;
                        dest=src+noOfCharacters;
                        copyArrayElementsIntoString(src, dest, hexArray);
                        tlv.setDssid(sb.toString());
                        sb.setLength(0);
                    }
                    else if((i+1)<arrayLength && hexArray[i+1].equals("26")) {
                        noOfCharacters= (char)Integer.parseInt(hexArray[i+2], 16);
                        src=i+3;
                        dest=src+noOfCharacters;
                        copyArrayElementsIntoString(src, dest, hexArray);
                        tlv.setMac(sb.toString());
                        sb.setLength(0);
                    }
                    else if((i+1)<arrayLength && hexArray[i+1].equals("36")) {
                        noOfCharacters= (char)Integer.parseInt(hexArray[i+2], 16);
                        src=i+3;
                        dest=src+noOfCharacters;
                        copyArrayElementsIntoString(src, dest, hexArray);
                        tlv.setAtc(sb.toString());
                        sb.setLength(0);
                    }
                    i=dest-1;
                    src=0;
                    dest=0;
                    continue;

                }
                if(hexArray[i].equals("DF")) {
                    if((i+1)<arrayLength && hexArray[i+1].equals("AE")) {

                        if((i+2)<arrayLength && hexArray[i+2].equals("05")) {
                            noOfCharacters= (char)Integer.parseInt(hexArray[i+3], 16);
                            src=i+4;
                            dest=src+noOfCharacters;
                            copyArrayElementsIntoString(src, dest, hexArray);
                            tlv.setCvb(sb.toString());
                            sb.setLength(0);
                        }
                        else if((i+2)<arrayLength && hexArray[i+2].equals("06")) {
                            noOfCharacters= (char)Integer.parseInt(hexArray[i+3], 16);
                            src=i+4;
                            dest=src+noOfCharacters;
                            copyArrayElementsIntoString(src, dest, hexArray);
                            tlv.setToken(sb.toString());
                            sb.setLength(0);
                        }

                    }
                    i=dest-1;
                    src=0;
                    dest=0;
                    continue;
                }
                /*if(hexArray[i].equals("90")) {
                    if((i+1)<arrayLength && hexArray[i+1].equals("00")) {

                    }
                }*/

            }catch(Exception e) {

            }

        }
    }
}

【问题讨论】:

  • 首先,您应该将输入的十六进制字符串解析为byte[]。无论如何,如果输入真的是 114 个十六进制数字,那么 split(" ") 将不会拆分任何内容,而只是返回一个元素的 String[],即整个输入,然后 hexArray[hexArray.length-3] 将抛出异常,并且您的任何代码都不会跑。再试一次!
  • 对不起,我粘贴了没有空格的输入字符串。实际字符串在每个字节后都有空格,我可以拆分它。
  • 那么您应该编辑问题并显示与代码实际匹配的数据版本。
  • TLV解码从cryptomathic在extranet.cryptomathic.com/tlvutils/index对不起,有在解码遇到了一些错误:对标签35短值,预期长度8397414651929375767755279014127412078567821808600920015574545401688638293030691230202797230783982154840628529348657308868018299,得到0 24未知标签35未知标签跨度>

标签: java tlv


【解决方案1】:

如果我理解你的问题是正确的。在找到Tag 后解析数据的Length 时,您可以忽略Data 中出现的重复Tag 以获取下一个Length 字节数。只考虑在LengthData 字节之外找到的标签。

【讨论】:

  • 例如这个字符串“240035E1319F080238309F370454363449DFAE0501419F260861742F754D6E4956DFAE060C3334726C5A6E6C6B75796B649F360200010”。标记“9F08”后面是字节 02,它指定接下来的两个字节作为数据,现在可能存在此标记也将成为另一个标记数据的一部分的情况,即使我读取下一个字节,在这种情况下我将如何区分。我有点困惑。
  • 您读取了一个标签,然后您读取了数据长度,现在您知道该特定标签有多少字节的数据。只需考虑下一个length 字节数作为数据。即使此数据中有tag,您也知道不必考虑它,因为现在您只是在读取数据。读完数据后,继续下一个标签。
  • 我创建了一个枚举映射,其中包含我感兴趣的标签,然后我循环遍历字符串,一次取一个字节两个字符,并检查它是否是一个标签,如果是的话如果不是标签的最后一个字节,则继续下一个字节或接下来的两个字符。我有一个布尔变量来查看它的标签或长度,以防万一在长度的情况下防止标签检查。
  • 所以当你找到你的标签时,你会读取接下来的 2 个字节的数据长度,对吗?所以在读取长度后说它是 x,所以现在接下来的 x 个字节将是数据。将布尔标志设置为 true 并开始遍历字符串 x 字节,当布尔标志为 true 时不查找标签,最后将布尔标志设置为 false,并查找下一个标签。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 2010-12-02
  • 2016-01-27
  • 2023-03-20
相关资源
最近更新 更多