题目描述
- 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; 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; 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; int len = 0; for(int j = 0; j < s.size(); j++){ len += cai(s[j]) * pow(16,j); } i += len; } } return 0; }
|