#include #include #include // 问题:将一个二进制流转换成可阅读的字符串,字符串为:大写字母加数字,去除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(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(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; }