Nilorea Library
C utilities for networking, threading, graphics
n_base64.c
Go to the documentation of this file.
1
8#include "nilorea/n_base64.h"
9#include <string.h>
10
11
13static const unsigned char pr2six[256] =
14{
15 /* ASCII table */
16 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
17 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
18 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
19 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
20 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
21 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
22 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
23 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
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, 64, 64, 64, 64, 64,
27 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
28 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,
30 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
31 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
32};
33
34
35
37static const bool ascii_upper_case_lookup_table[ 256 ] =
38{
39 /* ASCII table , upper from 65 to 90 */
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //16
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //64
44 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
45 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 //256
56};
57
58
59
61static const bool ascii_lower_case_lookup_table[ 256 ] =
62{
63 /* ASCII table , upper from 97 to 122 */
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //16
65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //64
68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
71 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, //128
72 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 //256
80};
81
82
83
84
90FORCE_INLINE bool n_isupper( char c )
91{
92 return ascii_upper_case_lookup_table[ (uint8_t)c ];
93}
94
95
96
103{
104 return ascii_lower_case_lookup_table[ (uint8_t)c ];
105}
106
107
108
115{
116 return ( ascii_lower_case_lookup_table[ (uint8_t)c ] || ascii_upper_case_lookup_table[ (uint8_t)c ] );
117}
118
119
120
127{
128 if( ascii_lower_case_lookup_table[ (uint8_t)c ] )
129 return ( c - 32 );
130 return c ;
131}
132
133
134
141{
142 if( ascii_upper_case_lookup_table[ (uint8_t)c ] )
143 return ( c + 32 );
144 return c ;
145}
146
152size_t n_base64_decode_len( N_STR *string )
153{
154 __n_assert( string , return 0 );
155 int nbytesdecoded;
156 register const unsigned char *bufin;
157 register int nprbytes;
158
159 bufin = (const unsigned char *) string -> data ;
160 while (pr2six[*(bufin++)] <= 63);
161
162 nprbytes = (bufin - (const unsigned char *) string -> data) - 1;
163 nbytesdecoded = ((nprbytes + 3) / 4) * 3;
164
165 return nbytesdecoded ;
166}
167
168
175{
176 size_t nbytesdecoded;
177 register const unsigned char *bufin;
178 register unsigned char *bufout;
179 register int nprbytes;
180
181 bufin = (const unsigned char *) bufcoded -> data ;
182 while (pr2six[*(bufin++)] <= 63);
183 nprbytes = (bufin - (const unsigned char *) bufcoded -> data) - 1;
184 nbytesdecoded = ( ( (nprbytes + 3) / 4) * 3 ) ;
185
186 N_STR *bufplain = new_nstr( nbytesdecoded + 1);
187 bufout = (unsigned char *) bufplain -> data ;
188 bufin = (const unsigned char *) bufcoded -> data ;
189
190 while (nprbytes > 4) {
191 *(bufout++) =
192 (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
193 *(bufout++) =
194 (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
195 *(bufout++) =
196 (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
197 bufin += 4;
198 nprbytes -= 4;
199 }
200
201 /* Note: (nprbytes == 1) would be an error, so just ignore that case */
202 if (nprbytes > 1) {
203 *(bufout++) =
204 (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
205 }
206 if (nprbytes > 2) {
207 *(bufout++) =
208 (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
209 }
210 if (nprbytes > 3) {
211 *(bufout++) =
212 (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
213 }
214
215 *(bufout++) = '\0';
216 nbytesdecoded -= (4 - nprbytes) & 3;
217
218 bufplain -> written = nbytesdecoded ;
219
220 return bufplain ;
221}
222
223
225static const char basis_64[] =
226"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
227
228
229
235size_t n_base64_encode_len( N_STR *string )
236{
237 __n_assert( string , return 0 );
238
239 return ( ( string -> written + 2 ) / 3 * 4 ) + 1 ;
240}
241
242
243
250{
251 size_t i = 0 ;
252 char *p = NULL ;
253 char *string = input -> data ;
254 size_t len = input -> written ;
255
256 size_t output_length = n_base64_encode_len( input );
257 if( output_length == 0 )
258 return NULL ;
259
260 N_STR *encoded = new_nstr( output_length + 1 );
261
262 p = encoded -> data ;
263 for (i = 0; i < len - 2; i += 3) {
264 *p++ = basis_64[(string[i] >> 2) & 0x3F];
265 *p++ = basis_64[((string[i] & 0x3) << 4) |
266 ((int) (string[i + 1] & 0xF0) >> 4)];
267 *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
268 ((int) (string[i + 2] & 0xC0) >> 6)];
269 *p++ = basis_64[string[i + 2] & 0x3F];
270 }
271 if (i < len) {
272 *p++ = basis_64[(string[i] >> 2) & 0x3F];
273 if (i == (len - 1)) {
274 *p++ = basis_64[((string[i] & 0x3) << 4)];
275 *p++ = '=';
276 }
277 else {
278 *p++ = basis_64[((string[i] & 0x3) << 4) |
279 ((int) (string[i + 1] & 0xF0) >> 4)];
280 *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
281 }
282 *p++ = '=';
283 }
284
285 *p++ = '\0';
286
287 encoded -> written = p - encoded -> data ;
288
289 return encoded ;
290}
#define __n_assert(__ptr, __ret)
macro to assert things
Definition: n_common.h:276
#define FORCE_INLINE
FORCE_INLINE portable macro.
Definition: n_common.h:141
FORCE_INLINE char n_tolower(char c)
is_alpha
Definition: n_base64.c:140
N_STR * n_base64_decode(N_STR *bufcoded)
decode a N_STR *string
Definition: n_base64.c:174
FORCE_INLINE bool n_isupper(char c)
test if char c is uppercase
Definition: n_base64.c:90
FORCE_INLINE char n_toupper(char c)
is_alpha
Definition: n_base64.c:126
FORCE_INLINE bool n_islower(char c)
test if char c is lowercase
Definition: n_base64.c:102
FORCE_INLINE bool n_isalpha(char c)
is_alpha
Definition: n_base64.c:114
N_STR * n_base64_encode(N_STR *input)
encode a N_STR *string
Definition: n_base64.c:249
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
Definition: n_str.c:215
A box including a string and his lenght.
Definition: n_str.h:173
size_t n_base64_decode_len(N_STR *string)
get the length of 'input' if it was base64 decoded
Definition: n_base64.c:152
static const char basis_64[]
static lookup base64 alphabet
Definition: n_base64.c:225
static const bool ascii_upper_case_lookup_table[256]
static upper case lookup ascii table
Definition: n_base64.c:37
static const bool ascii_lower_case_lookup_table[256]
static lower case lookup ascii table
Definition: n_base64.c:61
size_t n_base64_encode_len(N_STR *string)
get the length of string if it was base64 encoded
Definition: n_base64.c:235
static const unsigned char pr2six[256]
static lookup ascii table
Definition: n_base64.c:13
base64 encoding and decoding functions using N_STR