TLV解析II_100分_A/B复用卷_字符串/逻辑分析模拟/数据结构

TLV解析II

题目描述:

两端通过TLV格式的报文来通信,现在收到对端的一个TLV格式的消息包,要求生成匹配后的(tag,length,valueOffset)列表。
具体要求如下:
  (1)消息包中多组tag、length、value紧密排列,其中tag,length各占1字节(uint8 t),value所占字节数等于length的值
  (2)结果数组中tag值已知,需要填充每个 tag 对应数据的 length和valueOffset 值(valueOffset为value在原消息包中的起始偏移量 (从0开始,以字节为单位)),
即将消息包中的tag与结果数组中的tag进行匹配(可能存在匹配失败的情况,若结果数组中的tag在消息包中找不到,则ength和valueOffset都为0)
  (3)消息包和结果数组中的tag值都按升序排列,且不重复
  (4)此消息包未被篡改,但尾部可能不完整,不完整的一组TLV请丢弃掉

输入输出描述:

输入描述:

  第一行: 一个字符串,代表收到的消息包。字符串长度在10000以内。
  说明1: 字符串使用十六进制文本格式(字母为大写)来展示消息包的数据,
  如0F04ABABABAB代表一组TLV:
    前两个字符(0F)代表tag值为15,
    接下来两个字符 (04)代表length值为4字节,接下来8个字符即为4字节的value。
  说明2: 输入字符串中,每一组TLV紧密排列,中间无空格等分隔符
  第二行: 需要匹配的tag数量n (0 < n <1000).
  后面n行: 需要匹配的n个tag值 (十进制表示),递增排列。

输出描述:

  和需要匹配的 n个tag对应的n行匹配结果,每一行由长度和偏移量组成

示例1:

输入:
	0F04ABABABAB
	1
	15
输出:
	4 2
说明:
	tag15(十六进制OF)对应数据的长度为4,其value从第三个字节开始,因此偏移量为2

示例2:

输入:
	0F04ABABABAB1001FF
	2
	15
	17
输出:
	4 2
	0 0
说明:
	第二个tag匹配失败

解题思路:

  根据题目的意思,按顺序解析出相应的tag、length、value,题目并不困难,只需要维护好tag、length、value他们在原始字符串中的移动量即可。
  下图以输入为例子:

	0F04ABABABAB0E01BB
	2
	15
	14

所以最后输出

	4 2
	1 8

  解析详情:
在这里插入图片描述

代码:

public static void main(String[] args) {
	Scanner scanner = new Scanner(System.in);
	String original = scanner.nextLine();
	int n = Integer.parseInt(scanner.nextLine());
	Set<Integer> tagOffset = new HashSet<>();
	// 记录下要查询的目标tag
	for (int i = 0; i < n; i++) {
		tagOffset.add(Integer.parseInt(scanner.nextLine()));
	}

	// 开始解析
	int bound = original.length();
	// original.substring(left, right)是tag,一开始第一个tag占两个字符,所以left=0,right=2
	int left = 0;
	int right = 2;
	// 偏移量单位按照字符来计算,一开始tag、value就占掉4个字符,所以偏移量初始化为4
	int offset = 4;
	String[] res = new String[n];
	int index = 0;
	while (right <= bound) {
		int tag = Integer.parseInt(original.substring(left, right), 16);
		int length = Integer.parseInt(original.substring(left + 2, right + 2), 16);

		// 如果tag是要查询的目标tag
		if (tagOffset.contains(tag)) {
			// 如果长度value完整
			if (offset + (length * 2) <= bound) {
				// 偏移量要按照字节输出,所以除以 2
				res[index++] = length + " " + (offset / 2);
			} else {
				res[index++] = "0 0";
			}
		}

		// 更新偏移量
		offset = offset + length * 2 + 4;
		left += (length * 2) + 4;
		right += (length * 2) + 4;
	}

	// 输出结果
	for (int i = 0; i < n; i++) {
		System.out.println(res[i]);
	}
}

类似题目

TLV 解析 I

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值