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.字符串拼接
 */

 

posted @ 2020-03-13 14:01  ren_zhg1992  阅读(575)  评论(0)    收藏  举报