华为OD机试 - TLV解码(Java 2025 A卷 100分)

一、题目描述

TLV编码是按[Tag Length Value]格式进行编码的,一段码流中的信元用Tag标识,Tag在码流中唯一不重复,Length表示信元Value的长度,Value表示信元的值。

码流以某信元的Tag开头,Tag固定占一个字节,Length固定占两个字节,字节序为小端序。

现给定TLV格式编码的码流,以及需要解码的信元Tag,请输出该信元的Value。

输入码流的16进制字符中,不包括小写字母,且要求输出的16进制字符串中也不要包含小写字母;码流字符串的最大长度不超过50000个字节。

二、输入描述

输入的第一行为一个字符串,表示待解码信元的Tag;
输入的第二行为一个字符串,表示待解码的16进制码流,字节之间用空格分隔。

三、输出描述

输出一个字符串,表示待解码信元以16进制表示的Value。

四、测试用例

测试用例1:

1、输入

90
32 01 00 AE 90 02 00 01 02 30 03 00 AB 32 31 31 02 00 32 33 33 01 00

2、输出

01 02

3、说明

目标Tag为"90"。
码流中Tag为"90"的Value为"01 02"。

### 华为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、付费专栏及课程。

余额充值