Huawei OD computer-based test algorithm questions: TLV decoding

Table of contents

Question part

Analysis and ideas

Code


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)

Guess you like

Origin blog.csdn.net/ZiJinShi/article/details/132668464