实现Base16编码和解码

26 阅读2分钟

代码

#include <iostream>
#include <string>

static const char BASE16_ENC_TAB[] = "0123456789ABCDEF";

static const char BASE16_DEC_TAB[128] = {
    -1,                                      // 0
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 1-10
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 11-20
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 21-30
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 31-40
    -1, -1, -1, -1, -1, -1, -1, 0, 1, 2,  // 41-50
    3, 4, 5, 6, 7, 8, 9, -1, -1, -1,  // 51-60
    -1, -1, -1, -1, 10, 11, 12, 13, 14, 15,  // 61-70
};

int Base16Encode(const unsigned char* in, int size, char* out) {

    for (int i = 0; i < size; i++)
    {
        // 一个字节取出高4位和低4位
        char h = in[i] >> 4;  // 右移4位可以取出高位部分
        char l = in[i] & 0x0F;  // 与0x0F相与即可移除高位得到低位

        out[i * 2] = BASE16_ENC_TAB[h];  // 因为大小变为了两倍,所以需要乘以2, 使用BASE16_ENC_TAB找到对应的字符
        out[i * 2 + 1] = BASE16_ENC_TAB[l];
    }

    // base16转码后空间会扩大一倍, 一个字节转成了两个字符
    return size * 2;
}

int Base16Decode(const std::string &in, unsigned char* out) {

    // 将两个字符拼成一个字节
    for (int i = 0; i < in.size(); i+=2)
    {
        unsigned char ch = in[i];  // 高位
        unsigned char cl = in[i + 1];  // 低位

        unsigned char h = BASE16_DEC_TAB[ch];  // 转化成原来的值
        unsigned char l = BASE16_DEC_TAB[cl];  // 转化成原来的值

        // 两个4位拼成一个字节
        out[i / 2] = h << 4 | l;
    }

    return in.size() / 2;
}


int main(int argc, char* argv[]) {

    const unsigned char data[] = "测试代码test1234";

    int len = sizeof(data);
    char out1[1024] = { 0 }; // 编码后的字符串
    unsigned char out2[1024] = { 0 }; // 解码后的字符串

    std::cout << data << std::endl;

    int re = Base16Encode(data, len, out1);

    std::cout << re << ":" << out1 << std::endl;

    int re1 = Base16Decode(out1, out2);

    std::cout << re1 << ":" << out2 << std::endl;

    return 0;
}

测试结果

image.png