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
 |