86 lines
3.0 KiB
C++
86 lines
3.0 KiB
C++
#include <iostream>
|
|
#include <bitset>
|
|
#include <cstring>
|
|
|
|
// 问题:将一个二进制流转换成可阅读的字符串,字符串为:大写字母加数字,去除0和O,I和1相近字符。
|
|
|
|
const int g_bitNum = 5;
|
|
const char* g_Coder = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
|
|
int Encode(const char* pData, int nLen, char* res)
|
|
{
|
|
int totalLen = nLen * 8;
|
|
int resLen = totalLen / g_bitNum;
|
|
if (totalLen % g_bitNum != 0) ++resLen;
|
|
if (res == nullptr) {
|
|
return resLen;
|
|
}
|
|
for (int i = 0; i < resLen; ++i) {
|
|
unsigned char nIndex = 0;
|
|
int index = i * g_bitNum;
|
|
for (int j = 0; j < g_bitNum && index + j < totalLen; ++j) {
|
|
|
|
// bitValue 这一行只管取出下一位的值,放在哪里不管。
|
|
// index 是连续的(相当于大组里面内增,换个大组继续内增)
|
|
// index / 8 或者 index % 8 就是锁定第几组char的第几个,移动到最低位取出。
|
|
unsigned char bitValue = ((pData[index / 8] >> (7 - index % 8)) & 1);
|
|
|
|
// value 这一行只管把值放到对应的位置,与上面不要联系。
|
|
// 这里对 value 高位到低位的放
|
|
nIndex |= (bitValue << (g_bitNum - 1 - j));
|
|
|
|
// 关键点:value 和 bitValue 各管各的。
|
|
++index;
|
|
}
|
|
res[i] = g_Coder[nIndex];
|
|
}
|
|
res[resLen] = '\0';
|
|
return resLen;
|
|
}
|
|
|
|
int Decode(const char* pData, unsigned char* res)
|
|
{
|
|
int len = static_cast<int>(std::strlen(pData));
|
|
int codeBitCount = len * g_bitNum;
|
|
int resCnt = codeBitCount / 8;
|
|
if (res == nullptr) {
|
|
return resCnt;
|
|
}
|
|
std::memset(res, 0, resCnt * sizeof(char));
|
|
for (int i = 0; i < len; ++i) {
|
|
const char key = pData[i];
|
|
int nIndex = static_cast<int>(std::strchr(g_Coder, key) - g_Coder);
|
|
for (int j = 0; j < g_bitNum && i * g_bitNum + j < codeBitCount; ++j) {
|
|
// bitValue 这一行,只管取出每一位
|
|
int bitValue = ((nIndex >> (g_bitNum - 1 - j)) & 1);
|
|
// nOffset 是原始数据位索引
|
|
int nOffset = i * g_bitNum + j;
|
|
res[nOffset / 8] |= (bitValue << (7 - nOffset % 8));
|
|
}
|
|
}
|
|
return resCnt;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int data[] = {12345, 45678};
|
|
std::cout << "Original Data Len: " << sizeof(data) << std::endl;
|
|
char* szEncode = nullptr;
|
|
int size = Encode((const char*)data, sizeof(data), szEncode);
|
|
std::printf("Encode Data Len: %d\n", size);
|
|
szEncode = new char[size + 1];
|
|
Encode((const char*)data, sizeof(data), szEncode);
|
|
std::printf("Encode Data: %s\n", szEncode);
|
|
|
|
unsigned char * szDecode = nullptr;
|
|
int osize = Decode((const char *)szEncode, szDecode);
|
|
std::printf("Decode Data Len: %d\n", osize);
|
|
szDecode = new unsigned char [osize + 1];
|
|
Decode((const char*)szEncode, szDecode);
|
|
|
|
int* pInt = (int *)szDecode;
|
|
std::printf("Int[0]:%d, Int[1]:%d\n", pInt[0], pInt[1]);
|
|
delete[] szDecode;
|
|
delete[] szEncode;
|
|
return 0;
|
|
} |