【华为OD机试】TLV解析Ⅰ(C++ Python Java)2023 B卷

本文介绍了一个华为在线开发者(OD)机试题目,涉及到TLV编码的解析。给定TLV码流和特定Tag,需要解码对应信元的Value,并以16进制形式输出。题目描述了码流的格式,包括Tag、Length和Value的字节大小和顺序,以及输入输出的具体要求。解题关键在于正确匹配和解析码流。

时间限制:C/C++ 1秒,其他语言 2秒

空间限制:C/C++262144K,其他语言524288K

64bit IO Format:%lld

语言限定:
C(clang11), C++(clang++11), Pascal(fpc 3.0.2), Java(javac 1.8), Python2(2.7.3), 
PHP(7.4.7), C#(mcs5.4), ObjC(gcc 5.4), Pythen3(3.9), JavaScript Node(12.18.2), JavaScript V8(6.0.0),
Sqlite(3.7.9), R(4.0.3), Go(1.14.4), Ruby(2.7.1), Swift(5.3), matlab(Octave 5.2), Pypy2(pypy2.7.13),
Pypy3(pypy3.6.1), Rust(1.44), Scala(2.11.12), Kotlin(1.4.10), Groovy(3.0.6), TypeScript(4.1.2), Mysql(8.0)

本题可使用本地IDE编码,不能使用本地已有代码,无跳出限制,

编码后请点击”保存并调试“按钮进行代码提交。

题目描述:

TLV 编码是按 [ Tag Length Value ] 格式进行编码的,一段码流中的信元用Tag标识,

 Tag在码流中 唯一不重复 ,Length表示信元Value的长度,Value表示信元的值。

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

现给定TLV格

### 华为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
发出的红包

打赏作者

dijkstra2023

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

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

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

打赏作者

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

抵扣说明:

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

余额充值