TLV 解析 I

题目描述

  • TLV 编码是按 [ Tag Length Value ] 格式进行编码的,一段码流中的信元用Tag标识, Tag在码流中 唯一不重复 ,Length表示信元Value的长度,Value表示信元的值。
  • 码流以某信元的Tag开头,Tag固定占 一个字节,Length固定占 两个字节,字节序为 小端序
  • 现给定TLV格式编码的码流,以及需要解码的信元Tag,请输出该信元的Value。
  • 输入码流的16进制字符中,不包括小写字母,且要求输出的16进制字符串中也不要包含小写字母;
  • 码流字符串的最大长度不超过50000个字节。

输入描述:

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

输出描述:

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

示例 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

输出

32 33

样例解释

说明

  • 需要解析的信元的Tag是31,从码流的起始处开始匹配;
  • Tag为32的信元长度为1(01 00,小端序表示为1);
  • 第二个信元的Tag是90,其长度为2;
  • 第三个信元的Tag是30,其长度为3;
  • 第四个信元的Tag是31,其长度为2(02 00),所以返回长度后面的两个字节即可,即32 33。

思路

需要注意的是小端排序,例如01 00我们需要先把它翻转变为00 10去掉前面的00变为10,十进制就为1 * 16^0 + 0* 16^1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

//判断当前字符的十进制
int cai(char x){
if(isdigit(x)){
return x-'0';
}else{
return x-'A';
}
}

int main(){
string tag;
cin >> tag;
//要不然后面的getline读不到,忽略换行
cin.ignore();
vector<string> TLV;
string str;
getline(cin,str);
stringstream ss;
ss << str;
string p; //存储不含空格和换行的字符串
while(ss >> p){
TLV.push_back(p);
}
for(int i = 0; i < TLV.size(); i++){
if(TLV[i] == tag){
//处理小端输入
string s1 = TLV[i + 1], s2 = TLV[i + 2];
string s;
if(s2 == "00"){
s = s1;
}else{
s = s1 + s2;
}
reverse(s.begin(), s.end());
i += 2;
//后面value长度
int len = 0;
for(int j = 0; j < s.size(); j++){
len += cai(s[j]) * pow(16,j);
}
for(int j = 0; j < len; j++){
cout << TLV[i + j + 1] << " ";
}
cout << endl;
break;
}else{
//处理小端输入
string s1 = TLV[i + 1], s2 = TLV[i + 2];
string s;
if(s2 == "00"){
s = s1;
}else{
s = s1 + s2;
}
reverse(s.begin(), s.end());
i += 2;
//后面value长度
int len = 0;
for(int j = 0; j < s.size(); j++){
len += cai(s[j]) * pow(16,j);
}
i += len;
}
}
return 0;
}