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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#include <base64.hpp>
#include <cassert>
namespace base64
{
bool base64_encode(const gsl::cstring_span<> &input, std::string &output)
{
static const char encoding_data[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned int input_length = input.size();
// allocate space for output string
output.clear();
output.reserve(((input_length + 2) / 3) * 4);
// for each 3-bytes sequence from the input, extract 4 6-bits sequences and
// encode using
// encoding_data lookup table.
// if input do not contains enough chars to complete 3-byte sequence,use pad
// char '='
for (unsigned int i = 0; i < input_length; i++) {
int base64code0 = 0;
int base64code1 = 0;
int base64code2 = 0;
int base64code3 = 0;
base64code0 = (input[i] >> 2) & 0x3f; // 1-byte 6 bits
output += encoding_data[base64code0];
base64code1 = (input[i] << 4) & 0x3f; // 1-byte 2 bits +
if (++i < input_length) {
base64code1 |= (input[i] >> 4) & 0x0f; // 2-byte 4 bits
output += encoding_data[base64code1];
base64code2 = (input[i] << 2) & 0x3f; // 2-byte 4 bits +
if (++i < input_length) {
base64code2 |= (input[i] >> 6) & 0x03; // 3-byte 2 bits
base64code3 = input[i] & 0x3f; // 3-byte 6 bits
output += encoding_data[base64code2];
output += encoding_data[base64code3];
} else {
output += encoding_data[base64code2];
output += '=';
}
} else {
output += encoding_data[base64code1];
output += '=';
output += '=';
}
}
return true;
}
bool base64_decode(const gsl::cstring_span<> &input, std::string &output)
{
static const char nop = -1;
static const char decoding_data[] = {
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, 62, nop,
nop, nop, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, nop, nop,
nop, nop, nop, nop, nop, 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, nop, nop, nop, nop, nop, nop, 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, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
nop};
unsigned int input_length = input.size();
// allocate space for output string
output.clear();
output.reserve(((input_length + 2) / 3) * 4);
// for each 4-bytes sequence from the input, extract 4 6-bits sequences by
// droping first two bits
// and regenerate into 3 8-bits sequence
for (unsigned int i = 0; i < input_length; i++) {
char base64code0;
char base64code1;
char base64code2 = 0; // initialized to 0 to suppress warnings
char base64code3;
base64code0 = decoding_data[static_cast<int>(input[i])];
if (base64code0 == nop) // non base64 character
return false;
if (!(++i < input_length)) // we need at least two input bytes for first
// byte output
return false;
base64code1 = decoding_data[static_cast<int>(input[i])];
if (base64code1 == nop) // non base64 character
return false;
output += ((base64code0 << 2) | ((base64code1 >> 4) & 0x3));
if (++i < input_length) {
char c = input[i];
if (c == '=') { // padding , end of input
assert((base64code1 & 0x0f) == 0);
return true;
}
base64code2 = decoding_data[static_cast<int>(input[i])];
if (base64code2 == nop) // non base64 character
return false;
output += ((base64code1 << 4) & 0xf0) | ((base64code2 >> 2) & 0x0f);
}
if (++i < input_length) {
char c = input[i];
if (c == '=') { // padding , end of input
assert((base64code2 & 0x03) == 0);
return true;
}
base64code3 = decoding_data[static_cast<int>(input[i])];
if (base64code3 == nop) // non base64 character
return false;
output += (((base64code2 << 6) & 0xc0) | base64code3);
}
}
return true;
}
}
|