Nyx Node
Loading...
Searching...
No Matches
base64.c
1/* NyxNode
2 * Author: Jérôme ODIER <jerome.odier@lpsc.in2p3.fr>
3 * SPDX-License-Identifier: GPL-2.0-only (Mongoose backend) or GPL-3.0+
4 */
5
6/*--------------------------------------------------------------------------------------------------------------------*/
7
8#include "../nyx_node_internal.h"
9
10/*--------------------------------------------------------------------------------------------------------------------*/
11
12static const /*----*/ char BASE64_ENCODE_TABLE[] = {
13 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
14 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
15 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
16 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
17 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
18 '+', '/',
19};
20
21/*--------------------------------------------------------------------------------------------------------------------*/
22
23static const unsigned char BASE64_DECODE_TABLE[] = {
24 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
25 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
26 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
27 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
28 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
29 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
30 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
31 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
32};
33
34/*--------------------------------------------------------------------------------------------------------------------*/
35
36str_t nyx_base64_encode(size_t *result_len, size_t size, BUFF_t buff)
37{
38 if(size == 0x00 || buff == NULL)
39 {
40 if(result_len)
41 {
42 *result_len = 0x00;
43 }
44
45 return NULL;
46 }
47
48 /*----------------------------------------------------------------------------------------------------------------*/
49
50 size_t len = 4 * ((size + 2) / 3);
51
52 str_t str = nyx_memory_alloc(len + 1);
53
54 /*----------------------------------------------------------------------------------------------------------------*/
55
56 size_t div = size / 3;
57 size_t mod = size % 3;
58
59 const unsigned char *p = buff;
60 /*-*/ /*----*/ char *q = str;
61
62 /*----------------------------------------------------------------------------------------------------------------*/
63
64 for(size_t i = 0; i < div; i++)
65 {
66 uint32_t triple = (
67 ((uint32_t) p[0] << 16)
68 |
69 ((uint32_t) p[1] << 8)
70 |
71 ((uint32_t) p[2] << 0)
72 );
73
74 *q++ = BASE64_ENCODE_TABLE[(triple >> 18) & 0x3F];
75 *q++ = BASE64_ENCODE_TABLE[(triple >> 12) & 0x3F];
76 *q++ = BASE64_ENCODE_TABLE[(triple >> 6) & 0x3F];
77 *q++ = BASE64_ENCODE_TABLE[(triple >> 0) & 0x3F];
78
79 p += 3;
80 }
81
82 /*----------------------------------------------------------------------------------------------------------------*/
83
84 /**/ if(mod == 2)
85 {
86 uint32_t triple = (
87 ((uint32_t) p[0] << 16)
88 |
89 ((uint32_t) p[1] << 8)
90 );
91
92 *q++ = BASE64_ENCODE_TABLE[(triple >> 18) & 0x3F];
93 *q++ = BASE64_ENCODE_TABLE[(triple >> 12) & 0x3F];
94 *q++ = BASE64_ENCODE_TABLE[(triple >> 6) & 0x3F];
95 *q++ = '=';
96 }
97 else if(mod == 1)
98 {
99 uint32_t triple = (
100 ((uint32_t) p[0] << 16)
101 );
102
103 *q++ = BASE64_ENCODE_TABLE[(triple >> 18) & 0x3F];
104 *q++ = BASE64_ENCODE_TABLE[(triple >> 12) & 0x3F];
105 *q++ = '=';
106 *q++ = '=';
107 }
108
109 /*----------------------------------------------------------------------------------------------------------------*/
110
111 *q = '\0';
112
113 /*----------------------------------------------------------------------------------------------------------------*/
114
115 if(result_len)
116 {
117 *result_len = len;
118 }
119
120 return str;
121}
122
123/*--------------------------------------------------------------------------------------------------------------------*/
124
125buff_t nyx_base64_decode(size_t *result_size, size_t len, STR_t str)
126{
127 if(len == 0x00 || str == NULL)
128 {
129 if(result_size)
130 {
131 *result_size = 0x00;
132 }
133
134 return NULL;
135 }
136
137 /*----------------------------------------------------------------------------------------------------------------*/
138
139 size_t pad = (size_t) (str[len - 1] == '=')
140 +
141 (size_t) (str[len - 2] == '=')
142 ;
143
144 /*----------------------------------------------------------------------------------------------------------------*/
145
146 size_t size = (len / 4) * 3 - pad;
147
148 buff_t buff = nyx_memory_alloc(size + 1);
149
150 /*----------------------------------------------------------------------------------------------------------------*/
151
152 size_t blocks = (len / 4) - (
153 pad > 0 ? 1 : 0
154 );
155
156 const /*----*/ char *p = str;
157 /*-*/ unsigned char *q = buff;
158
159 /*----------------------------------------------------------------------------------------------------------------*/
160
161 for(size_t i = 0; i < blocks; i++)
162 {
163 uint32_t triple = (
164 ((uint32_t) BASE64_DECODE_TABLE[(int) p[0]] << 18)
165 |
166 ((uint32_t) BASE64_DECODE_TABLE[(int) p[1]] << 12)
167 |
168 ((uint32_t) BASE64_DECODE_TABLE[(int) p[2]] << 6)
169 |
170 ((uint32_t) BASE64_DECODE_TABLE[(int) p[3]] << 0)
171 );
172
173 *q++ = (triple >> 16) & 0xFF;
174 *q++ = (triple >> 8) & 0xFF;
175 *q++ = (triple >> 0) & 0xFF;
176
177 p += 4;
178 }
179
180 /*----------------------------------------------------------------------------------------------------------------*/
181
182 /**/ if(pad == 1)
183 {
184 uint32_t triple = (
185 ((uint32_t) BASE64_DECODE_TABLE[(int) p[0]] << 18)
186 |
187 ((uint32_t) BASE64_DECODE_TABLE[(int) p[1]] << 12)
188 |
189 ((uint32_t) BASE64_DECODE_TABLE[(int) p[2]] << 6)
190 );
191
192 *q++ = (triple >> 16) & 0xFF;
193 *q++ = (triple >> 8) & 0xFF;
194 }
195 else if(pad == 2)
196 {
197 uint32_t triple = (
198 ((uint32_t) BASE64_DECODE_TABLE[(int) p[0]] << 18)
199 |
200 ((uint32_t) BASE64_DECODE_TABLE[(int) p[1]] << 12)
201 );
202
203 *q++ = (triple >> 16) & 0xFF;
204 }
205
206 /*----------------------------------------------------------------------------------------------------------------*/
207
208 *q = '\0';
209
210 /*----------------------------------------------------------------------------------------------------------------*/
211
212 if(result_size)
213 {
214 *result_size = size;
215 }
216
217 return buff;
218}
219
220/*--------------------------------------------------------------------------------------------------------------------*/
#define STR_t
Alias for const char *.
Definition nyx_node.h:71
__NYX_NULLABLE__ buff_t nyx_memory_alloc(__NYX_ZEROABLE__ size_t size)
Similar to libc malloc except that a memory overflow causes the node to stop.
#define buff_t
Alias for void *.
Definition nyx_node.h:67
#define BUFF_t
Alias for const void *.
Definition nyx_node.h:68
#define str_t
Alias for char *.
Definition nyx_node.h:70
__NYX_NULLABLE__ str_t nyx_base64_encode(__NYX_NULLABLE__ size_t *result_len, __NYX_ZEROABLE__ size_t size, __NYX_NULLABLE__ BUFF_t buff)
Encodes a buffer using the Base64 algorithm.
__NYX_NULLABLE__ buff_t nyx_base64_decode(__NYX_NULLABLE__ size_t *result_size, __NYX_ZEROABLE__ size_t len, __NYX_NULLABLE__ STR_t str)
Decodes a string using the Base64 algorithm.