1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "base64_utils.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include <array> 19094332d3Sopenharmony_cinamespace OHOS { 20094332d3Sopenharmony_cinamespace HDI { 21094332d3Sopenharmony_cinamespace Drm { 22094332d3Sopenharmony_cinamespace V1_0 { 23094332d3Sopenharmony_ci#ifdef __linux__ 24094332d3Sopenharmony_cistatic std::string BASE64_CHARS = /* NOLINT */ 25094332d3Sopenharmony_ci "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 26094332d3Sopenharmony_ci "abcdefghijklmnopqrstuvwxyz" 27094332d3Sopenharmony_ci "0123456789+/"; 28094332d3Sopenharmony_ci 29094332d3Sopenharmony_cistatic constexpr const uint32_t CHAR_ARRAY_LENGTH_THREE = 3; 30094332d3Sopenharmony_cistatic constexpr const uint32_t CHAR_ARRAY_LENGTH_FOUR = 4; 31094332d3Sopenharmony_ci 32094332d3Sopenharmony_cienum BASE64_ENCODE_CONSTANT : uint8_t { 33094332d3Sopenharmony_ci BASE64_ENCODE_MASK1 = 0xfc, 34094332d3Sopenharmony_ci BASE64_ENCODE_MASK2 = 0x03, 35094332d3Sopenharmony_ci BASE64_ENCODE_MASK3 = 0x0f, 36094332d3Sopenharmony_ci BASE64_ENCODE_MASK4 = 0x3f, 37094332d3Sopenharmony_ci BASE64_ENCODE_MASK5 = 0xf0, 38094332d3Sopenharmony_ci BASE64_ENCODE_MASK6 = 0xc0, 39094332d3Sopenharmony_ci BASE64_ENCODE_OFFSET2 = 2, 40094332d3Sopenharmony_ci BASE64_ENCODE_OFFSET4 = 4, 41094332d3Sopenharmony_ci BASE64_ENCODE_OFFSET6 = 6, 42094332d3Sopenharmony_ci BASE64_ENCODE_INDEX0 = 0, 43094332d3Sopenharmony_ci BASE64_ENCODE_INDEX1 = 1, 44094332d3Sopenharmony_ci BASE64_ENCODE_INDEX2 = 2, 45094332d3Sopenharmony_ci}; 46094332d3Sopenharmony_ci 47094332d3Sopenharmony_cienum BASE64_DECODE_CONSTANT : uint8_t { 48094332d3Sopenharmony_ci BASE64_DECODE_MASK1 = 0x30, 49094332d3Sopenharmony_ci BASE64_DECODE_MASK2 = 0xf, 50094332d3Sopenharmony_ci BASE64_DECODE_MASK3 = 0x3c, 51094332d3Sopenharmony_ci BASE64_DECODE_MASK4 = 0x3, 52094332d3Sopenharmony_ci BASE64_DECODE_OFFSET2 = 2, 53094332d3Sopenharmony_ci BASE64_DECODE_OFFSET4 = 4, 54094332d3Sopenharmony_ci BASE64_DECODE_OFFSET6 = 6, 55094332d3Sopenharmony_ci BASE64_DECODE_INDEX0 = 0, 56094332d3Sopenharmony_ci BASE64_DECODE_INDEX1 = 1, 57094332d3Sopenharmony_ci BASE64_DECODE_INDEX2 = 2, 58094332d3Sopenharmony_ci BASE64_DECODE_INDEX3 = 3, 59094332d3Sopenharmony_ci}; 60094332d3Sopenharmony_ci 61094332d3Sopenharmony_cistatic inline bool IsBase64Char(const char c) 62094332d3Sopenharmony_ci{ 63094332d3Sopenharmony_ci return (isalnum(c) || (c == '+') || (c == '/')); 64094332d3Sopenharmony_ci} 65094332d3Sopenharmony_ci 66094332d3Sopenharmony_cistatic inline void MakeCharFour(const std::array<uint8_t, CHAR_ARRAY_LENGTH_THREE> &charArrayThree, 67094332d3Sopenharmony_ci std::array<uint8_t, CHAR_ARRAY_LENGTH_FOUR> &charArrayFour) 68094332d3Sopenharmony_ci{ 69094332d3Sopenharmony_ci const uint8_t table[CHAR_ARRAY_LENGTH_FOUR] = { 70094332d3Sopenharmony_ci static_cast<uint8_t>((charArrayThree[BASE64_ENCODE_INDEX0] & BASE64_ENCODE_MASK1) >> BASE64_ENCODE_OFFSET2), 71094332d3Sopenharmony_ci static_cast<uint8_t>(((charArrayThree[BASE64_ENCODE_INDEX0] & BASE64_ENCODE_MASK2) << BASE64_ENCODE_OFFSET4) + 72094332d3Sopenharmony_ci ((charArrayThree[BASE64_ENCODE_INDEX1] & BASE64_ENCODE_MASK5) >> BASE64_ENCODE_OFFSET4)), 73094332d3Sopenharmony_ci static_cast<uint8_t>(((charArrayThree[BASE64_ENCODE_INDEX1] & BASE64_ENCODE_MASK3) << BASE64_ENCODE_OFFSET2) + 74094332d3Sopenharmony_ci ((charArrayThree[BASE64_ENCODE_INDEX2] & BASE64_ENCODE_MASK6) >> BASE64_ENCODE_OFFSET6)), 75094332d3Sopenharmony_ci static_cast<uint8_t>(charArrayThree[BASE64_ENCODE_INDEX2] & BASE64_ENCODE_MASK4), 76094332d3Sopenharmony_ci }; 77094332d3Sopenharmony_ci for (size_t index = 0; index < CHAR_ARRAY_LENGTH_FOUR; ++index) { 78094332d3Sopenharmony_ci charArrayFour[index] = table[index]; 79094332d3Sopenharmony_ci } 80094332d3Sopenharmony_ci} 81094332d3Sopenharmony_ci 82094332d3Sopenharmony_cistatic inline void MakeCharTree(const std::array<uint8_t, CHAR_ARRAY_LENGTH_FOUR> &charArrayFour, 83094332d3Sopenharmony_ci std::array<uint8_t, CHAR_ARRAY_LENGTH_THREE> &charArrayThree) 84094332d3Sopenharmony_ci{ 85094332d3Sopenharmony_ci const uint8_t table[CHAR_ARRAY_LENGTH_THREE] = { 86094332d3Sopenharmony_ci static_cast<uint8_t>((charArrayFour[BASE64_DECODE_INDEX0] << BASE64_DECODE_OFFSET2) + 87094332d3Sopenharmony_ci ((charArrayFour[BASE64_DECODE_INDEX1] & BASE64_DECODE_MASK1) >> BASE64_DECODE_OFFSET4)), 88094332d3Sopenharmony_ci static_cast<uint8_t>(((charArrayFour[BASE64_DECODE_INDEX1] & BASE64_DECODE_MASK2) << BASE64_DECODE_OFFSET4) + 89094332d3Sopenharmony_ci ((charArrayFour[BASE64_DECODE_INDEX2] & BASE64_DECODE_MASK3) >> BASE64_DECODE_OFFSET2)), 90094332d3Sopenharmony_ci static_cast<uint8_t>(((charArrayFour[BASE64_DECODE_INDEX2] & BASE64_DECODE_MASK4) << BASE64_DECODE_OFFSET6) + 91094332d3Sopenharmony_ci charArrayFour[BASE64_DECODE_INDEX3]), 92094332d3Sopenharmony_ci }; 93094332d3Sopenharmony_ci for (size_t index = 0; index < CHAR_ARRAY_LENGTH_THREE; ++index) { 94094332d3Sopenharmony_ci charArrayThree[index] = table[index]; 95094332d3Sopenharmony_ci } 96094332d3Sopenharmony_ci} 97094332d3Sopenharmony_ci 98094332d3Sopenharmony_ci#endif 99094332d3Sopenharmony_ci 100094332d3Sopenharmony_cistd::string Encode(const std::string &source) 101094332d3Sopenharmony_ci{ 102094332d3Sopenharmony_ci#ifdef __linux__ 103094332d3Sopenharmony_ci auto it = source.begin(); 104094332d3Sopenharmony_ci std::string ret; 105094332d3Sopenharmony_ci size_t index = 0; 106094332d3Sopenharmony_ci std::array<uint8_t, CHAR_ARRAY_LENGTH_THREE> charArrayThree = { 0 }; 107094332d3Sopenharmony_ci std::array<uint8_t, CHAR_ARRAY_LENGTH_FOUR> charArrayFour = { 0 }; 108094332d3Sopenharmony_ci 109094332d3Sopenharmony_ci while (it != source.end()) { 110094332d3Sopenharmony_ci charArrayThree[index] = *it; 111094332d3Sopenharmony_ci ++index; 112094332d3Sopenharmony_ci ++it; 113094332d3Sopenharmony_ci if (index != CHAR_ARRAY_LENGTH_THREE) { 114094332d3Sopenharmony_ci continue; 115094332d3Sopenharmony_ci } 116094332d3Sopenharmony_ci MakeCharFour(charArrayThree, charArrayFour); 117094332d3Sopenharmony_ci for (auto idx : charArrayFour) { 118094332d3Sopenharmony_ci ret += BASE64_CHARS[idx]; 119094332d3Sopenharmony_ci } 120094332d3Sopenharmony_ci index = 0; 121094332d3Sopenharmony_ci } 122094332d3Sopenharmony_ci if (index == 0) { 123094332d3Sopenharmony_ci return ret; 124094332d3Sopenharmony_ci } 125094332d3Sopenharmony_ci 126094332d3Sopenharmony_ci for (auto i = index; i < CHAR_ARRAY_LENGTH_THREE; ++i) { 127094332d3Sopenharmony_ci charArrayThree[i] = 0; 128094332d3Sopenharmony_ci } 129094332d3Sopenharmony_ci MakeCharFour(charArrayThree, charArrayFour); 130094332d3Sopenharmony_ci 131094332d3Sopenharmony_ci for (size_t i = 0; i < index + 1; ++i) { 132094332d3Sopenharmony_ci ret += BASE64_CHARS[charArrayFour[i]]; 133094332d3Sopenharmony_ci } 134094332d3Sopenharmony_ci 135094332d3Sopenharmony_ci while (index < CHAR_ARRAY_LENGTH_THREE) { 136094332d3Sopenharmony_ci ret += '='; 137094332d3Sopenharmony_ci ++index; 138094332d3Sopenharmony_ci } 139094332d3Sopenharmony_ci return ret; 140094332d3Sopenharmony_ci#else 141094332d3Sopenharmony_ci return {}; 142094332d3Sopenharmony_ci#endif 143094332d3Sopenharmony_ci} 144094332d3Sopenharmony_ci 145094332d3Sopenharmony_cistd::string Decode(const std::string &encoded) 146094332d3Sopenharmony_ci{ 147094332d3Sopenharmony_ci#ifdef __linux__ 148094332d3Sopenharmony_ci auto it = encoded.begin(); 149094332d3Sopenharmony_ci size_t index = 0; 150094332d3Sopenharmony_ci std::array<uint8_t, CHAR_ARRAY_LENGTH_THREE> charArrayThree = { 0 }; 151094332d3Sopenharmony_ci std::array<uint8_t, CHAR_ARRAY_LENGTH_FOUR> charArrayFour = { 0 }; 152094332d3Sopenharmony_ci std::string ret; 153094332d3Sopenharmony_ci 154094332d3Sopenharmony_ci while (it != encoded.end() && IsBase64Char(*it)) { 155094332d3Sopenharmony_ci charArrayFour[index] = *it; 156094332d3Sopenharmony_ci ++index; 157094332d3Sopenharmony_ci ++it; 158094332d3Sopenharmony_ci if (index != CHAR_ARRAY_LENGTH_FOUR) { 159094332d3Sopenharmony_ci continue; 160094332d3Sopenharmony_ci } 161094332d3Sopenharmony_ci for (index = 0; index < CHAR_ARRAY_LENGTH_FOUR; ++index) { 162094332d3Sopenharmony_ci charArrayFour[index] = BASE64_CHARS.find(static_cast<char>(charArrayFour[index])); 163094332d3Sopenharmony_ci } 164094332d3Sopenharmony_ci MakeCharTree(charArrayFour, charArrayThree); 165094332d3Sopenharmony_ci for (auto idx : charArrayThree) { 166094332d3Sopenharmony_ci ret += static_cast<char>(idx); 167094332d3Sopenharmony_ci } 168094332d3Sopenharmony_ci index = 0; 169094332d3Sopenharmony_ci } 170094332d3Sopenharmony_ci if (index == 0) { 171094332d3Sopenharmony_ci return ret; 172094332d3Sopenharmony_ci } 173094332d3Sopenharmony_ci 174094332d3Sopenharmony_ci for (auto i = index; i < CHAR_ARRAY_LENGTH_FOUR; ++i) { 175094332d3Sopenharmony_ci charArrayFour[i] = 0; 176094332d3Sopenharmony_ci } 177094332d3Sopenharmony_ci for (unsigned char &i : charArrayFour) { 178094332d3Sopenharmony_ci i = BASE64_CHARS.find(static_cast<char>(i)); 179094332d3Sopenharmony_ci } 180094332d3Sopenharmony_ci MakeCharTree(charArrayFour, charArrayThree); 181094332d3Sopenharmony_ci 182094332d3Sopenharmony_ci for (size_t i = 0; i < index - 1; i++) { 183094332d3Sopenharmony_ci ret += static_cast<char>(charArrayThree[i]); 184094332d3Sopenharmony_ci } 185094332d3Sopenharmony_ci return ret; 186094332d3Sopenharmony_ci#else 187094332d3Sopenharmony_ci return {}; 188094332d3Sopenharmony_ci#endif 189094332d3Sopenharmony_ci} 190094332d3Sopenharmony_ci} // V1_0 191094332d3Sopenharmony_ci} // Drm 192094332d3Sopenharmony_ci} // HDI 193094332d3Sopenharmony_ci} // OHOS