galaxy 1.0.0
Real-Time C++23 Game Programming Framework. Built on data-driven design principles and agile software engineering.
Loading...
Searching...
No Matches
Base64.cpp
Go to the documentation of this file.
1
7
10
11#include "Base64.hpp"
12
13#ifdef GALAXY_WIN_PLATFORM
16#endif
17
18// clang-format off
19constexpr const char encoding_table[] = {
20 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
21 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
22 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
23 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
24 '4', '5', '6', '7', '8', '9', '+', '/'
25};
26
27constexpr const unsigned char decoding_table[] = {
28 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
29 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
30 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57,
31 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8,
32 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64,
33 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
34 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
35 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
36 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
37 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
38 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
39 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
40 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
41 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
42 64, 64
43};
44
45// clang-format on
46
47namespace galaxy
48{
49 namespace math
50 {
51 std::string encode_base64(const std::string& input)
52 {
53 try
54 {
55 if (!input.empty())
56 {
57 const auto in_len = input.size();
58 const auto out_len = static_cast<std::size_t>(4 * ((in_len + 2) / 3));
59
60 auto output = std::string(out_len, '\0');
61 char* p = &output[0];
62
63 std::size_t i = 0;
64 for (i = 0; i < in_len - 2; i += 3)
65 {
66 *p++ = encoding_table[(input[i] >> 2) & 0x3F];
67 *p++ = encoding_table[((input[i] & 0x3) << 4) | (static_cast<int>(input[i + 1] & 0xF0) >> 4)];
68 *p++ = encoding_table[((input[i + 1] & 0xF) << 2) | (static_cast<int>(input[i + 2] & 0xC0) >> 6)];
69 *p++ = encoding_table[input[i + 2] & 0x3F];
70 }
71
72 if (i < in_len)
73 {
74 *p++ = encoding_table[(input[i] >> 2) & 0x3F];
75
76 if (i == (in_len - 1))
77 {
78 *p++ = encoding_table[((input[i] & 0x3) << 4)];
79 *p++ = '=';
80 }
81 else
82 {
83 *p++ = encoding_table[((input[i] & 0x3) << 4) | (static_cast<int>(input[i + 1] & 0xF0) >> 4)];
84 *p++ = encoding_table[((input[i + 1] & 0xF) << 2)];
85 }
86
87 *p++ = '=';
88 }
89
90 return output;
91 }
92 else
93 {
94 GALAXY_LOG(GALAXY_ERROR, "Attempted to encode an empty string.");
95 return {};
96 }
97 }
98 catch (const std::exception& e)
99 {
100 GALAXY_LOG(GALAXY_ERROR, "{0}.", e.what());
101 return {};
102 }
103 }
104
105 std::string decode_base64(const std::string& input)
106 {
107 try
108 {
109 if (!input.empty())
110 {
111 const auto in_len = input.size();
112
113 if (in_len % 4 != 0)
114 {
115 GALAXY_LOG(GALAXY_ERROR, "Input data size is not a multiple of 4");
116 return {};
117 }
118 else
119 {
120 auto out_len = static_cast<std::size_t>(in_len / 4 * 3);
121
122 if (input[in_len - 1] == '=')
123 {
124 out_len--;
125 }
126
127 if (input[in_len - 2] == '=')
128 {
129 out_len--;
130 }
131
132 auto output = std::string(out_len, '\0');
133
134 for (std::size_t i = 0, j = 0; i < in_len;)
135 {
136 const std::uint32_t a = input[i] == '=' ? 0 & i++ : decoding_table[static_cast<int>(input[i++])];
137 const std::uint32_t b = input[i] == '=' ? 0 & i++ : decoding_table[static_cast<int>(input[i++])];
138 const std::uint32_t c = input[i] == '=' ? 0 & i++ : decoding_table[static_cast<int>(input[i++])];
139 const std::uint32_t d = input[i] == '=' ? 0 & i++ : decoding_table[static_cast<int>(input[i++])];
140
141 const std::uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6);
142
143 if (j < out_len)
144 {
145 output[j++] = (triple >> 2 * 8) & 0xFF;
146 }
147
148 if (j < out_len)
149 {
150 output[j++] = (triple >> 1 * 8) & 0xFF;
151 }
152
153 if (j < out_len)
154 {
155 output[j++] = (triple >> 0 * 8) & 0xFF;
156 }
157 }
158
159 return output;
160 }
161 }
162 else
163 {
164 GALAXY_LOG(GALAXY_ERROR, "Attempted to decode an empty string.");
165 return {};
166 }
167 }
168 catch (const std::exception& e)
169 {
170 GALAXY_LOG(GALAXY_ERROR, "{0}.", e.what());
171 return {};
172 }
173 }
174 } // namespace math
175} // namespace galaxy
176
177#ifdef GALAXY_WIN_PLATFORM
179#endif
constexpr const char encoding_table[]
Base64.cpp galaxy.
Definition Base64.cpp:19
constexpr const unsigned char decoding_table[]
Definition Base64.cpp:27
#define GALAXY_LOG(level, msg,...)
Definition Log.hpp:29
#define GALAXY_ERROR
Definition Log.hpp:25
#define GALAXY_DISABLE_WARNING_POP
Definition Pragma.hpp:44
#define GALAXY_DISABLE_WARNING(x)
Definition Pragma.hpp:45
#define GALAXY_DISABLE_WARNING_PUSH
Pragma.hpp galaxy.
Definition Pragma.hpp:43
std::string encode_base64(const std::string &input)
Compresses string into Base64.
Definition Base64.cpp:51
std::string decode_base64(const std::string &input)
Decompresses string into Base64.
Definition Base64.cpp:105
Timer.hpp galaxy.
Definition Async.hpp:17