• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "base64.h"
17 
18 namespace panda::es2panda::util {
Base64Encode(const std::string & inputString)19 std::string Base64Encode(const std::string &inputString)
20 {
21     size_t strLen = inputString.length();
22     size_t encodedStrLen = strLen / TO_TRANSFORM_CHAR_NUM * TRANSFORMED_CHAR_NUM;
23     if (strLen % TO_TRANSFORM_CHAR_NUM != 0) {
24         encodedStrLen += TRANSFORMED_CHAR_NUM;
25     }
26     std::string encodedRes = std::string(encodedStrLen, '\0');
27     const char* base64CharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
28     for (size_t i = 0, j = 0; i < encodedRes.length() - 2; i += TRANSFORMED_CHAR_NUM, j += TO_TRANSFORM_CHAR_NUM) {
29         // convert three 8bit into four 6bit; then add two 0 bit in each 6 bit
30         // former 00 + first 6 bits of the first char
31         encodedRes[i] = base64CharSet[(inputString[j] & 0xff) >> 2];
32         // 00 + the last 2 bits of the first char + the first 4 bits of the second char
33         encodedRes[i + 1] = base64CharSet[(inputString[j] & 0x03) << 4 | (inputString[j + 1] & 0xf0) >> 4];
34         // 00 + last 4 bits of the second char + the first 2 bits of the third char
35         encodedRes[i + 2] = base64CharSet[(inputString[j + 1] & 0x0f) << 2 | (inputString[j + 2] & 0xc0) >> 6];
36         // 00 + the last 6 bits of the third char
37         encodedRes[i + 3] = base64CharSet[inputString[j + 2] & 0x3f];
38     }
39     switch (strLen % TO_TRANSFORM_CHAR_NUM) {
40         case 1:
41             encodedRes[encodedRes.length() - 2] = '=';
42             encodedRes[encodedRes.length() - 1] = '=';
43             break;
44         case 2:
45             encodedRes[encodedRes.length() - 1] = '=';
46             break;
47         default:
48             break;
49     }
50     return encodedRes;
51 }
52 
Base64Decode(const std::string & base64String)53 std::string Base64Decode(const std::string &base64String)
54 {
55     const int decodeTable[] = {
56         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
57         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
58         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
59         -1, -1, -1, -1, -1, -1, -1,
60         62,   //  '+'
61         -1, -1, -1,
62         63,   // '/'
63         52, 53, 54, 55, 56, 57, 58, 59, 60, 61,   // '0'~'9'
64         -1, -1, -1, -1, -1, -1, -1,
65         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
66         14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,   // 'A'~'Z'
67         -1, -1, -1, -1, -1, -1,
68         26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
69         39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51    // 'a'~'z'
70     };
71 
72     size_t strLen = base64String.length();
73     size_t decodedStrLen = strLen / TRANSFORMED_CHAR_NUM * TO_TRANSFORM_CHAR_NUM;
74     if (base64String.find("==") != std::string::npos) {
75         decodedStrLen -= std::string("==").length();
76     } else if (base64String.find("=") != std::string::npos) {
77         decodedStrLen -= std::string("=").length();
78     }
79     std::string decodedRes = std::string(decodedStrLen, '\0');
80     int firstChar = 0;
81     int secondChar = 0;
82     int thirdChar = 0;
83     int fourthChar = 0;
84     for (size_t i = 0, j = 0; i < strLen - 2; i += TRANSFORMED_CHAR_NUM, j += TO_TRANSFORM_CHAR_NUM) {
85         firstChar = decodeTable[static_cast<unsigned char>(base64String[i])];
86         secondChar = decodeTable[static_cast<unsigned char>(base64String[i + 1])];
87         thirdChar = decodeTable[static_cast<unsigned char>(base64String[i + 2])];
88         fourthChar = decodeTable[static_cast<unsigned char>(base64String[i + 3])];
89 
90         if (firstChar == -1 || secondChar == -1) {
91             return "";
92         }
93         // the last 6 bit of the first char + the 2~3 bit of the second char(first 4 bit - 00)
94         decodedRes[j] = (firstChar << 2) | (secondChar >> 4);
95         if (j == decodedStrLen - 1) {
96             break;
97         }
98         if (thirdChar == -1) {
99             return "";
100         }
101         // the last 4 bit of the second char +  the 2~5 bit of the third char(first 6 bit - 00)
102         decodedRes[j + 1] = (secondChar << 4) | (thirdChar >> 2);
103         if (j + 1 == decodedStrLen - 1) {
104             break;
105         }
106         if (fourthChar == -1) {
107             return "";
108         }
109         // the last 2 bit of the third char + the last 6 bit of the fourth char
110         decodedRes[j + 2] = (thirdChar << 6) | fourthChar;
111     }
112     return decodedRes;
113 }
114 }  // namespace panda::es2panda::util
115