E-TLV解码(100p)

TLV解码

问题描述

TLV(Tag-Length-Value)编码是一种常用的数据编码格式。在这个编码中,每个数据元素由三部分组成:

  1. Tag:标识数据类型,固定占用 1 个字节。
  2. Length:表示 Value 的长度,固定占用 2 个字节,采用小端序。
  3. Value:实际数据内容,长度由 Length 决定。

现给定一个 TLV 格式编码的 16 进制字符串(码流),以及需要解码的特定 Tag,请解析并输出该 Tag 对应的 Value。

输入格式

输入包含两行:

  1. 第一行是一个字符串,表示需要解码的 Tag。
  2. 第二行是一个字符串,表示 TLV 编码的 16 进制码流,字节之间用空格分隔。

输出格式

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

样例输入1

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

样例输出1

32 33

样例解释

样例 解释说明
样例1 需要解析的信元的 Tag 是 31。从码流的起始处开始匹配:
1. 第一个信元的 Tag 是 32,长度为 1(01 00,小端序表示为 1);
2. 第二个信元的 Tag 是 90,长度为 2;
3. 第三个信元的 Tag 是 30,长度为 3;
4. 第四个信元的 Tag 是 31,长度为 2(02 00)。
因此,返回长度后面的两个字节,即 32 33。

数据范围

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

题解

模拟

这道题目要求我们解析 TLV(Tag-Length-Value)编码的数据流。解题的关键在于正确理解 TLV 的结构和小端序的概念。

首先,我们需要逐字节遍历输入的码流。对于每个数据元素,我们需要:

  1. 读取 1 个字节作为 Tag。
  2. 读取接下来的 2 个字节作为 Length,注意使用小端序解析。
  3. 根据 Length 的值,读取相应长度的 Value。

在这个过程中,我们需要特别注意以下几点:

  1. 小端序的处理:Length 占用两个字节,但是低位字节在前,高位字节在后。例如,"01 00" 表示长度为 1,而不是 256。

  2. 16 进制字符串的处理:输入的码流是以空格分隔的 16 进制字符串,我们需要正确地将其转换为实际的字节值。

  3. Tag 的匹配:我们需要持续遍历码流,直到找到与输入 Tag 匹配的数据元素。

  4. Value 的提取:一旦找到匹配的 Tag,我们需要根据其 Length 提取正确长度的 Value。

参考代码

  • Python
def parse_tlv(tag, stream):
    # 将空格分隔的16进制字符串转换为字节列表
    bytes_list = [int(b, 16) for b in stream.split()]
    i = 0
    while i < len(bytes_list):
        # 读取当前Tag
        current_tag = bytes_list[i]
        i += 1
        
        # 读取Length(小端序)
        length = bytes_list[i] + (bytes_list[i+1] << 8)
        i += 2
        
        # 如果找到匹配的Tag,返回Value
        if current_tag == int(tag, 16):
            return ' '.join([f'{b:02X}' for b in bytes_list[i:i+length]])
        
        # 否则跳过当前Value
        i += length
    
    # 如果没有找到匹配的Tag,返回空字符串
    return ''

# 读取输入
tag = input().strip()
stream = input().strip()

# 解析TLV并输出结果
result = parse_tlv(tag, stream)
print(result)
  • C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LEN 100000

// 将16进制字符转换为整数
int hex_to_int(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
    return -1;
}

// 解析TLV编码
char* parse_tlv(int tag, unsigned char* stream, int stream_len) {
    int i = 0;
    while (i < stream_len) {
        int current_tag = stream[i++];
        int length = stream[i] + (stream[i+1] << 8);
        i += 2;

        if (current_tag == tag) {
            char* result = (char*)malloc(length * 3);
            for (int j = 0; j < length; j++) {
                sprintf(result + j*3, "%02X ", stream[i+j]);
            }
            result[length*3-1] = '\0';
            return result;
        }

        i += length;
    }
    return "";
}

int main() {
 

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论

相关推荐

认真搞学习:这个真喷不了,你是我见过最美的牛客女孩
点赞 评论 收藏
分享
04-30 21:35
已编辑
长安大学 C++
晓沐咕咕咕:评论区没被女朋友好好对待过的计小将可真多。觉得可惜可以理解,毕竟一线大厂sp。但是骂楼主糊涂的大可不必,说什么会被社会毒打更是丢人。女朋友体制内生活有保障,读研女朋友还供着,都准备订婚了人家两情相悦,二线本地以后两口子日子美滋滋,哪轮到你一个一线城市房子都买不起的996清高计小将在这说人家傻😅
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务