Train_RFID_Linux/base/CBase64/CBase64.h

153 lines
5.3 KiB
C
Raw Normal View History

/*
* Copyright(C) 2020. Huawei Technologies Co.,Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _CBASE64_H_
#define _CBASE64_H_
namespace {
const int SHIFT_NUMBER_2 = 2;
const int SHIFT_NUMBER_4 = 4;
const int SHIFT_NUMBER_6 = 6;
const int SHIFT_NUMBER_8 = 8;
const int SHIFT_NUMBER_12 = 12;
const int SHIFT_NUMBER_16 = 16;
const int SHIFT_NUMBER_18 = 18;
const int EACH_STEP_SIZE = 4;
const int NORMAL_NUMBER_1 = 1;
const int NORMAL_NUMBER_2 = 2;
const int NORMAL_NUMBER_3 = 3;
}
class CBase64 {
public:
CBase64() = default;
~CBase64() = default;
/*
* base64 encode
* @param data input data
* @param dataSize data size
* @return base64 string
*/
static std::string Encode(const std::string &buffer, int dataSize)
{
// coding table
const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string result;
const char *data = buffer.c_str();
unsigned char tmp[EACH_STEP_SIZE] = {0};
int lineLength = 0;
const int turnBufferLength = 3;
const int maxLineLength = 76;
for (int i = 0; i < (int) (dataSize / turnBufferLength); i++) {
tmp[NORMAL_NUMBER_1] = *data++;
tmp[NORMAL_NUMBER_2] = *data++;
tmp[NORMAL_NUMBER_3] = *data++;
result += EncodeTable[tmp[NORMAL_NUMBER_1] >> SHIFT_NUMBER_2];
result += EncodeTable[((tmp[NORMAL_NUMBER_1] << SHIFT_NUMBER_4) |
(tmp[NORMAL_NUMBER_2] >> SHIFT_NUMBER_4)) & 0x3F];
result += EncodeTable[((tmp[NORMAL_NUMBER_2] << SHIFT_NUMBER_2) |
(tmp[NORMAL_NUMBER_3] >> SHIFT_NUMBER_6)) & 0x3F];
result += EncodeTable[tmp[NORMAL_NUMBER_3] & 0x3F];
if (lineLength += EACH_STEP_SIZE, lineLength == maxLineLength) {
lineLength = 0;
}
}
int Mod = dataSize % turnBufferLength;
if (Mod == NORMAL_NUMBER_1) {
tmp[NORMAL_NUMBER_1] = *data++;
result += EncodeTable[(tmp[NORMAL_NUMBER_1] & 0xFC) >> SHIFT_NUMBER_2];
result += EncodeTable[((tmp[NORMAL_NUMBER_1] & 0x03) << SHIFT_NUMBER_4)];
result += "==";
} else if (Mod == NORMAL_NUMBER_2) {
tmp[NORMAL_NUMBER_1] = *data++;
tmp[NORMAL_NUMBER_2] = *data++;
result += EncodeTable[(tmp[NORMAL_NUMBER_1] & 0xFC) >> SHIFT_NUMBER_2];
result += EncodeTable[((tmp[NORMAL_NUMBER_1] & 0x03) << SHIFT_NUMBER_4) |
((tmp[NORMAL_NUMBER_2] & 0xF0) >> SHIFT_NUMBER_4)];
result += EncodeTable[((tmp[NORMAL_NUMBER_2] & 0x0F) << SHIFT_NUMBER_2)];
result += "=";
}
return result;
}
/*
* base64 decode
* @param data base64 encoded string
* @param dataSize data size
* @param OutByte
* @return
*/
static std::string Decode(const std::string &buffer, int dataSize, int &outSize)
{
const char decodeTable[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62, // '+'
0, 0, 0,
63, // '/'
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
0, 0, 0, 0, 0, 0,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
};
const char *data = buffer.c_str();
std::string result;
int nValue;
int i = 0;
while (i < dataSize) {
if (*data != '\r' && *data != '\n') {
nValue = decodeTable[(unsigned char) (*data++)] << SHIFT_NUMBER_18;
nValue += decodeTable[(unsigned char) (*data++)] << SHIFT_NUMBER_12;
result += (nValue & 0x00FF0000) >> SHIFT_NUMBER_16;
outSize++;
if (*data == '=') {
i += EACH_STEP_SIZE;
continue;
}
nValue += decodeTable[(unsigned char) (*data++)] << SHIFT_NUMBER_6;
result += (nValue & 0x0000FF00) >> SHIFT_NUMBER_8;
outSize++;
if (*data != '=') {
nValue += decodeTable[(unsigned char) (*data++)];
result += nValue & 0x000000FF;
outSize++;
}
i += EACH_STEP_SIZE;
} else {
data++;
i++;
}
}
return result;
}
};
#endif