...
1 // This file is under GNU General Public License 3.0
12 static char translate_char_to_bits(char input) {
13 if (input >= 65 && input <= 90)
15 if (input >= 97 && input <= 122)
16 return input - 71; // 97 - 26
17 if (input >= 48 && input <= 57)
18 return input + 4; // 52 - 48
23 if (input == ' ' || input == '\r' || input == '\n')
28 static bool _is_whitespace(const char in) {
40 static size_t subtract_whitespace(const char* input, int length) {
41 size_t actual_size = length;
43 const char* curr = input;
44 for (i = 0; i < length; i++, curr++) {
45 if (_is_whitespace(*curr))
51 static void trim_end(const char* input, int* length) {
52 const char* end = input + *length;
54 int start_length = *length;
58 for (i = 0; i < start_length; i++) {
59 if (!_is_whitespace(*(--end)))
61 (*length) = (*length) - 1;
65 char next_char(const char** input_ptr, const char* end) {
66 const char* input = *input_ptr;
73 if (_is_whitespace(this_ch))
82 // 4 chars = 3 output bytes
83 bloblist_t* base64_str_to_binary_blob(const char* input, int length) {
87 trim_end(input, &length);
89 const char* input_curr;
91 const char* input_end = input_curr + length;
92 length = subtract_whitespace(input, length);
93 size_t final_length = (length / 4) * 3;
95 // padded -- FIXME: whitespace in between ==!!!!
96 if (*(input_end - 1) == '=') {
99 if (*(input_end - 2) == '=')
104 int leftover = length % 4;
118 void* blobby = calloc(final_length, 1);
119 char* blobby_curr = (char*)blobby;
121 // if the last 1 or 2 bytes are padded, we do those after
122 size_t number_of_rounds = final_length / 3;
126 // full 3-byte rounds
127 for (cycle = 0; cycle < number_of_rounds; cycle++) {
128 char byte_array[] = {0,0,0};
129 char in_val = next_char(&input_curr, input_end);
131 goto pEp_error; // can ALSO happen when input_curr == input_end,
132 // which simply shouldn't happen, since we're
133 // interating based on expected OUTPUT, not
136 char out_val = translate_char_to_bits(in_val);
140 byte_array[0] |= out_val << 2;
142 in_val = next_char(&input_curr, input_end);
145 out_val = translate_char_to_bits(in_val);
149 byte_array[0] |= out_val >> 4;
150 byte_array[1] = out_val << 4;
152 in_val = next_char(&input_curr, input_end);
155 out_val = translate_char_to_bits(in_val);
159 byte_array[1] |= out_val >> 2;
160 byte_array[2] = out_val << 6;
162 in_val = next_char(&input_curr, input_end);
165 out_val = translate_char_to_bits(in_val);
169 byte_array[2] |= out_val;
171 // Now write everything to the blob
172 *blobby_curr++ = byte_array[0];
173 *blobby_curr++ = byte_array[1];
174 *blobby_curr++ = byte_array[2];
177 int last_bytes = final_length % 3;
179 if (last_bytes != 0) {
183 char in_val = next_char(&input_curr, input_end);
186 char out_val = translate_char_to_bits(in_val);
189 byte_1 = out_val << 2;
190 in_val = next_char(&input_curr, input_end);
193 out_val = translate_char_to_bits(in_val);
196 byte_1 |= out_val >> 4;
197 *blobby_curr++ = byte_1;
199 if (last_bytes == 2) {
200 byte_2 = out_val << 4;
201 in_val = next_char(&input_curr, input_end);
205 out_val = translate_char_to_bits(in_val);
209 byte_2 |= out_val >> 2;
210 *blobby_curr++ = byte_2;
214 return new_bloblist((char*)blobby, final_length, NULL, NULL);