华为OD机试 - TLV格式(Java 2025 C卷 100分)

本文介绍了华为OD机试中关于TLV格式消息包的处理,包括题目描述、输入输出要求、解题思路及Java算法源码。内容涉及从十六进制字符串解析tag、length和valueOffset,以及如何匹配给定的tag并输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、题目描述

两端通过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在消息包中找不到,则length和valueOffset都为0)。
  3. 消息包和结果数组职工的tag值都按升序排序,且不重复。
  4. 此消息包未被篡改,但尾部可能不完整,不完整的一组TLV请丢弃掉。

二、输入描述

第一行:一个字符,代表收到的消息包。字符串长度在10000以内。

  • 说明1:字符串使用十六进制文本格式(字母为大写)来展示消息包的数据,如0F04ABABABAB代表一组TLV:前两个字符(OF)代表tag值为15,接下来两个字符(04)代表length值为4字节,接下来8个字符即为4字节的value。
  • 说明2:输入字符串中,每一组TLV紧密排列,中间无空格等分隔符

第二行:需要匹配的tag数量n(0 < n < 1000)
后面N行:需要匹配n个tag值(十进制

### 华为OD TLV解码 示例代码及注意事项 #### 解析TLV编码结构 TLV编码按照[Tag Length Value]格式进行编码。一段码流中的信元由`Tag`标识,`Tag`在码流中唯一不重复,`Length`表示信元`Value`的长度,而`Value`则代表信元的具体值[^1]。 #### 输入输出描述 输入的第一行为一个字符串,表示待解码信元的`Tag`; 输入的第二行为一个字符串,表示待解码的16进制码流,字节之间用空格隔。输出应是一个字符串,表示待解码信元以16进制表示的`Value`,其中不应包含小写字母[^3]。 #### Java实现示例 下面提供了一个基于上述要求编写的Java版本的TLV解码函数: ```java import java.util.Scanner; public class TLVDecoder { public static String decode(String tag, String hexStream) { byte[] bytes = hexStringToByteArray(hexStream.replace(" ", "")); int index = 0; while (index < bytes.length) { // Extract the current tag from stream. StringBuilder currentTagBuilder = new StringBuilder(); currentTagBuilder.append(byteToHex(bytes[index])); if (!currentTagBuilder.toString().equals(tag)) { index++; continue; // Skip to next iteration as this is not our target tag. } // Move past the tag and read length which occupies two bytes in little endian format. int valueLength = ((bytes[index + 2] & 0xFF) << 8) | (bytes[index + 1] & 0xFF); index += 3; // Advance over tag and length fields // Read 'value' based on its specified length. StringBuilder valueBuilder = new StringBuilder(); for(int i=0;i<valueLength && index+i<bytes.length;++i){ valueBuilder.append(byteToHex(bytes[index + i]).toUpperCase()); } return valueBuilder.toString(); // Return found value immediately upon discovery of matching tag. } throw new IllegalArgumentException("Specified tag does not exist within provided hexadecimal string."); } private static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; } private static String byteToHex(final byte b) { char[] digits = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char[] buf = new char[2]; buf[0] = digits[(b >>> 4) & 0x0F]; buf[1] = digits[b & 0x0F]; return new String(buf); } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); try{ System.out.println(decode(scanner.nextLine(),scanner.nextLine())); }catch(IllegalArgumentException e){ System.err.println(e.getMessage()); } } } ``` 此程序接收两行标准输入作为参数并打印出相应的十六进制`Value`。如果指定标签不存在,则抛出异常提示错误消息[^4]。 #### 注意事项 - `Tag`固定占用一字节,`Length`字段固定占用二字节,并采用小端序存储。 - 对于任何不符合预期的情况(比如找不到对应的`Tag`),应当适当地处理这些情况而不是简单地忽略它们。 - 需要注意的是,在实际应用环境中可能还需要考虑更多边界条件和性能优化等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值