Table of contents
Question part
topic | TLV encoding |
difficulty | easy |
Question description | TLV encoding is encoded according to the [Tag Length Value] format. The cells in a code stream are identified by Tag. The Tag is the only one in the code stream that is not repeated. Length represents the length of the cell Value, and Value represents the value of the cell. The code stream starts with the Tag of a certain cell. Tag always occupies one byte, Length always occupies two bytes, and the byte order is little endian. Now given the code stream encoded in TLV format and the cell tag that needs to be decoded, please output the Value of the cell. The 16 mechanism characters of the input code stream do not include lowercase letters, and the output hexadecimal string is required not to contain lowercase letters; the maximum length of the code stream string does not exceed 50,000 bytes. |
Enter description | The first line of input is a string, representing the Tag of the cell to be decoded; the second line of input is a string, representing the hexadecimal code stream to be decoded, with spaces separating bytes. |
Output description | Output a string representing the Value in hexadecimal of the cell to be decoded. |
Additional information | none |
--------------------------------------------------------------------------------------- |
|
Example | |
Example 1 | |
enter | 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 |
output | 32 33 |
illustrate | The Tag of the cell that needs to be parsed is 31. Matching starts from the beginning of the code stream. The length of the cell with Tag 32 is 1 (01 00, expressed as 1 in little endian order); the Tag of the second cell is 90 , its length is 2; the Tag of the third cell is 30, its length is 3; the Tag of the fourth cell is 31, its length is 2 (02 00), so the two bytes after the returned length are Yes, that is 32 33. |
Analysis and ideas
Question interpretation :
In the question, there are two lines of input. The second line is the TLV information flow. The TLV information flow consists of multiple cells, and each cell consists of Tag, Length, and Value; the first line is Tag, which is the Tag of a TLV cell.
The question requires finding the cell corresponding to the Tag in the first line from the multiple cells in the second line. Then output the Value of this cell.
In the input example, the first line specifies that the cell's Tag is 31, and the information flow input in the second line contains 5 cells, namely 32, 90, 30, 31, and 33. We find the cell with Tag 31, which is 31 02 00 32 33 , where 31 is Tag, 02 00 (i.e. 2) is the length, then the two following bytes 32 33 are Value, so the final result is output for 32 33.
Analysis and ideas :
This question only needs to find the corresponding informant from the information flow based on the specified Tag and output its Value. It does not involve too complex logical algorithms. The implementation is as follows:
1. Record the number entered in the first line and set it as variable Tag.
2. Go through the information flow entered in the second line one by one. When traversing, first determine whether the first input is equal to tag:
- If it is equal to Tag, continue to traverse the next 2 bytes, calculate the length (according to little endian order), set it as the variable length, and then output the next length bytes, which is the final output. Exit the program after output.
- If it is not equal to Tag, continue to traverse the next 2 bytes, calculate the length, set it to the variable length, then skip the next length bytes, and then continue to step 2.
This algorithm only needs to traverse the input of the second row once, the time complexity is O(n), only 2 additional auxiliary variables are needed, and the space complexity is O(1).
Code
Java code
import java.util.Scanner;
/**
* TLV解码
* @since 2023.09.04
* @version 0.2
* @author Frank
*
*/
public class LTV_Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
// 第一行输入的tag
String tag = sc.nextLine();
// 第二行输入的TLV数据流
String stream = sc.nextLine();
String[] tlvStream = stream.split(" ");
processLTVSolution( tag, tlvStream );
}
}
private static void processLTVSolution( String tag, String tlvStream[] )
{
int i = 0;
while (i < tlvStream.length) {
String tagTmp = tlvStream[i];
String lengthStr = tlvStream[i + 2] + tlvStream[i + 1];
int length = Integer.parseInt(lengthStr, 16);
// 已找到,输出
if ( !tagTmp.equals( tag )) {
// 没有找到Tag,略过,寻找下一个
i += ( 3 + length);
continue;
}
StringBuilder outputSB = new StringBuilder();
for (int j = 0; j < length; j++) {
outputSB.append(tlvStream[i + j + 3]);
if (j != length - 1) {
outputSB.append(" ");
}
}
System.out.println(outputSB.toString());
return;
}
}
}
JavaScript code
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
while (line = await readline()) {
// 第一行数据
var tag = line;
// 第二行数据转换成数组
line = await readline();
var ltvs = line.split(" ");
processLTVSolution(tag, ltvs);
}
}();
function processLTVSolution(tag, ltvs) {
var i = 0;
while (i < ltvs.length) {
var tagTmp = ltvs[i];
var lengthStr = ltvs[i + 2] + ltvs[i + 1];
var length = parseInt(lengthStr, 16);
// 没有找到Tag,略过,寻找下一个
if (tagTmp != tag) {
i += (3 + length);
continue;
}
// 已找到,输出
var output = "";
for (var j = 0; j < length; j++) {
output += (ltvs[i + j + 3]);
if (j != length - 1) {
output += " ";
}
}
console.log(output);
return;
}
}
(over)