153 lines
5.3 KiB
C
153 lines
5.3 KiB
C
|
|
/*
|
||
|
|
* 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
|