1fc223305Sopenharmony_ci/*
2fc223305Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3fc223305Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fc223305Sopenharmony_ci * you may not use this file except in compliance with the License.
5fc223305Sopenharmony_ci * You may obtain a copy of the License at
6fc223305Sopenharmony_ci *
7fc223305Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8fc223305Sopenharmony_ci *
9fc223305Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fc223305Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fc223305Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fc223305Sopenharmony_ci * See the License for the specific language governing permissions and
13fc223305Sopenharmony_ci * limitations under the License.
14fc223305Sopenharmony_ci */
15fc223305Sopenharmony_ci
16fc223305Sopenharmony_ci#include "base64_helper.h"
17fc223305Sopenharmony_ci#include <vector>
18fc223305Sopenharmony_ci#include "log_print.h"
19fc223305Sopenharmony_ci
20fc223305Sopenharmony_cinamespace OHOS {
21fc223305Sopenharmony_cinamespace NativePreferences {
22fc223305Sopenharmony_cistatic const uint8_t base64Encoder[] =
23fc223305Sopenharmony_ci    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
24fc223305Sopenharmony_ci
25fc223305Sopenharmony_cistatic const uint8_t base64Decoder[] = {
26fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
27fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
28fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62,  -1, -1, -1, 63,
29fc223305Sopenharmony_ci    52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  -1, -1, -1, -1, -1, -1,
30fc223305Sopenharmony_ci    -1, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
31fc223305Sopenharmony_ci    15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  -1, -1, -1, -1, -1,
32fc223305Sopenharmony_ci    -1, 26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,
33fc223305Sopenharmony_ci    41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  -1, -1, -1, -1, -1,
34fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
35fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
38fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
39fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
40fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
41fc223305Sopenharmony_ci    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
42fc223305Sopenharmony_ci};
43fc223305Sopenharmony_ci
44fc223305Sopenharmony_ciconst uint32_t BASE64_DEST_UNIT_SIZE = 4;
45fc223305Sopenharmony_ciconst uint32_t BASE64_SRC_UNIT_SIZE = 3;
46fc223305Sopenharmony_ciconst uint32_t BASE64_ONE_PADDING = 1;
47fc223305Sopenharmony_ciconst uint32_t BASE64_TWO_PADDING = 2;
48fc223305Sopenharmony_ciconst uint8_t BASE64_INVALID = 0xFF;
49fc223305Sopenharmony_ciconst uint8_t BASE64_MASK1 = 0x03;
50fc223305Sopenharmony_ciconst uint8_t BASE64_MASK2 = 0x0F;
51fc223305Sopenharmony_ciconst uint8_t BASE64_MASK3 = 0x3F;
52fc223305Sopenharmony_ciconst uint8_t BASE64_SHIFT_HIBYTE = 2;
53fc223305Sopenharmony_ciconst uint8_t BASE64_SHIFT = 4;
54fc223305Sopenharmony_ciconst uint8_t BASE64_SHIFT_LOBYTE = 6;
55fc223305Sopenharmony_ci
56fc223305Sopenharmony_cistd::string Base64Helper::Encode(const std::vector<uint8_t> &input)
57fc223305Sopenharmony_ci{
58fc223305Sopenharmony_ci    std::string result = "";
59fc223305Sopenharmony_ci    uint32_t index = 0;
60fc223305Sopenharmony_ci    for (uint32_t len = input.size(); len > 0; len -= BASE64_SRC_UNIT_SIZE) {
61fc223305Sopenharmony_ci        result += base64Encoder[input.at(index) >> BASE64_SHIFT_HIBYTE];
62fc223305Sopenharmony_ci        uint8_t code = (input.at(index++) & BASE64_MASK1) << BASE64_SHIFT;
63fc223305Sopenharmony_ci        if (len > BASE64_ONE_PADDING) {
64fc223305Sopenharmony_ci            result += base64Encoder[code | (input.at(index) >> BASE64_SHIFT)];
65fc223305Sopenharmony_ci            code = (input.at(index++) & BASE64_MASK2) << BASE64_SHIFT_HIBYTE;
66fc223305Sopenharmony_ci            if (len > BASE64_TWO_PADDING) {
67fc223305Sopenharmony_ci                result += base64Encoder[code | (input.at(index) >> BASE64_SHIFT_LOBYTE)];
68fc223305Sopenharmony_ci                result += base64Encoder[input.at(index++) & BASE64_MASK3];
69fc223305Sopenharmony_ci            } else {
70fc223305Sopenharmony_ci                result += base64Encoder[code];
71fc223305Sopenharmony_ci                result += "=";
72fc223305Sopenharmony_ci                break;
73fc223305Sopenharmony_ci            }
74fc223305Sopenharmony_ci        } else {
75fc223305Sopenharmony_ci            result += base64Encoder[code];
76fc223305Sopenharmony_ci            result += "==";
77fc223305Sopenharmony_ci            break;
78fc223305Sopenharmony_ci        }
79fc223305Sopenharmony_ci    }
80fc223305Sopenharmony_ci    return result;
81fc223305Sopenharmony_ci}
82fc223305Sopenharmony_ci
83fc223305Sopenharmony_cibool Base64Helper::Decode(const std::string &input, std::vector<uint8_t> &output)
84fc223305Sopenharmony_ci{
85fc223305Sopenharmony_ci    if (input.length() % BASE64_DEST_UNIT_SIZE != 0) {
86fc223305Sopenharmony_ci        return false;
87fc223305Sopenharmony_ci    }
88fc223305Sopenharmony_ci    uint32_t index = 0;
89fc223305Sopenharmony_ci    std::vector<uint8_t> result {};
90fc223305Sopenharmony_ci    while (index < input.length()) {
91fc223305Sopenharmony_ci        uint8_t ch1 = base64Decoder[static_cast<uint8_t>(input.at(index++))];
92fc223305Sopenharmony_ci        uint8_t ch2 = base64Decoder[static_cast<uint8_t>(input.at(index++))];
93fc223305Sopenharmony_ci        if (ch1 == BASE64_INVALID || ch2 == BASE64_INVALID) {
94fc223305Sopenharmony_ci            return false;
95fc223305Sopenharmony_ci        }
96fc223305Sopenharmony_ci        result.emplace_back((ch1 << BASE64_SHIFT_HIBYTE) | (ch2 >> BASE64_SHIFT));
97fc223305Sopenharmony_ci        if (input.at(index) == '=') {
98fc223305Sopenharmony_ci            break;
99fc223305Sopenharmony_ci        }
100fc223305Sopenharmony_ci        uint8_t ch3 = base64Decoder[static_cast<uint8_t>(input.at(index++))];
101fc223305Sopenharmony_ci        if (ch3 == BASE64_INVALID) {
102fc223305Sopenharmony_ci            return false;
103fc223305Sopenharmony_ci        }
104fc223305Sopenharmony_ci        result.emplace_back((ch2 << BASE64_SHIFT) | (ch3 >> BASE64_SHIFT_HIBYTE));
105fc223305Sopenharmony_ci        if (input.at(index) == '=') {
106fc223305Sopenharmony_ci            break;
107fc223305Sopenharmony_ci        }
108fc223305Sopenharmony_ci        uint8_t ch4 = base64Decoder[static_cast<uint8_t>(input.at(index++))];
109fc223305Sopenharmony_ci        if (ch4 == BASE64_INVALID) {
110fc223305Sopenharmony_ci            return false;
111fc223305Sopenharmony_ci        }
112fc223305Sopenharmony_ci        result.emplace_back((ch3 << BASE64_SHIFT_LOBYTE) | ch4);
113fc223305Sopenharmony_ci    }
114fc223305Sopenharmony_ci    output = result;
115fc223305Sopenharmony_ci    return true;
116fc223305Sopenharmony_ci}
117fc223305Sopenharmony_ci} // End of namespace NativePreferences
118fc223305Sopenharmony_ci} // End of namespace OHOS
119