C++流
根据输入字符串,按规则进行TLV编码。规则如下:
所有字符均为数字,则类型(T)为1,进行5421压缩编码(下有解释),长度(L)和内容(V)用来描述编码后的二进制码流。其他所有输入均按字符串处理,类型(T)为2,长度(L)和内容(V)用来描述该字符串,L和V中均不包括结束符。
输出为TLV字节码流,要求:前2字节为类型(T),接下来4字节为长度(L),后续为内容(V),字节序使用网络序(大端)。
5421压缩编码:
| 十进制数 | 二进制数 | 十六进制数 |
|---|---|---|
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 2 | 0010 | 2 |
| 3 | 0011 | 3 |
| 4 | 0100 | 4 |
| 5 | 1000 | 8 |
| 6 | 1001 | 9 |
| 7 | 1010 | a |
| 8 | 1011 | b |
| 9 | 1100 | c |
指用4bit来描述单个十进制数字,每个bit的权重分别为5/4/2/1,编码后每个字节可以描述两个十进制数字;奇数位数字,高位补0后参与编码。例如:45 -> 0x48,456 -> 0x04 0x89。
输入为单行字符串,不包含换行符。用例保证输入字符串长度范围[0,255]。输出为码流字符串,码流中每个字节由十六进制两位数表示,字母a-f小写,码流字节间由单个空格分隔。行末无空格。
输入:"456"
输出:"00 01 00 00 00 02 04 89"
输入:"abc"
输出:"00 02 00 00 00 03 61 62 63"
代码:
#include <iostream> #include <string> #include <iomanip> #include <sstream> using namespace std; static char trans[] = { '0', '1', '2', '3', '4', '8', '9', 'a', 'b', 'c'}; bool isAllNum(string str) { for (auto ch : str) { if (ch < '0' || ch > '9') { return false; } } return true; } string tlvEncode(string str) { string retStr = ""; // 数字 if (isAllNum(str)) { retStr += "00 01 00 00 00 "; // 由于题干上写了长度保证[0,255]内,所以长度只占用四字节的最后一个字节即可满足。 size_t len = (str.length() + 1) / 2; // 除2并向上取整 // 将整形长度的十六进制写入字符串 stringstream ss; string strLen = ""; ss << setw(2) << setfill('0') << hex << len; ss >> strLen; retStr = retStr + strLen; // 奇数 if (str.length() % 2 != 0) { retStr = retStr + "0" + trans[str[0] - '0']; for(size_t i = 1; i < str.length() - 1; i += 2) { // 每次读取两个 retStr = retStr + " " + trans[str[i] - '0'] + trans[str[i+1] - '0']; cout << retStr << endl; } } else { // 偶数 for(size_t i = 0; i < str.length() - 1; i += 2) { retStr = retStr + " " + trans[str[i] - '0'] + trans[str[i+1] - '0']; } } } else { // 字符串 retStr += "00 02 00 00 00"; // 将整形长度的十六进制写入字符串 size_t len = str.length(); stringstream ss; string strLen = ""; ss << setw(2) << setfill('0') << hex << len; ss >> strLen; retStr = retStr + " " + strLen; for (auto ch : str) { stringstream ss; string tmpStr = ""; ss << setw(2) << setfill('0') << hex << (int)ch; // 这里必须要将ascii强转为对应的整形 ss >> tmpStr; retStr = retStr + " " + tmpStr; } } return retStr; } int main() { string str = "abcdabcdabcdabcd"; string ret = tlvEncode(str); cout << ret; return 0; }
/* 这道题目主要考察: * 1.数字的十六进制转字符串:可以使用C++流 * 2.数字转accii码:直接强转一下即可 * 3.字符串拼接 */

浙公网安备 33010602011771号