2 * See Licensing and Copyright notice in naev.h
6 * compliant with rfc3548
17 /* encode table - base 64 alphabet as defined by the rfc */
18 static const char cb64
[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
19 /* generate decode table at compile time */
86 static const signed char cd64
[256] = { /* makes it much faster */
87 B64 (0), B64 (1), B64 (2), B64 (3),
88 B64 (4), B64 (5), B64 (6), B64 (7),
89 B64 (8), B64 (9), B64 (10), B64 (11),
90 B64 (12), B64 (13), B64 (14), B64 (15),
91 B64 (16), B64 (17), B64 (18), B64 (19),
92 B64 (20), B64 (21), B64 (22), B64 (23),
93 B64 (24), B64 (25), B64 (26), B64 (27),
94 B64 (28), B64 (29), B64 (30), B64 (31),
95 B64 (32), B64 (33), B64 (34), B64 (35),
96 B64 (36), B64 (37), B64 (38), B64 (39),
97 B64 (40), B64 (41), B64 (42), B64 (43),
98 B64 (44), B64 (45), B64 (46), B64 (47),
99 B64 (48), B64 (49), B64 (50), B64 (51),
100 B64 (52), B64 (53), B64 (54), B64 (55),
101 B64 (56), B64 (57), B64 (58), B64 (59),
102 B64 (60), B64 (61), B64 (62), B64 (63),
103 B64 (64), B64 (65), B64 (66), B64 (67),
104 B64 (68), B64 (69), B64 (70), B64 (71),
105 B64 (72), B64 (73), B64 (74), B64 (75),
106 B64 (76), B64 (77), B64 (78), B64 (79),
107 B64 (80), B64 (81), B64 (82), B64 (83),
108 B64 (84), B64 (85), B64 (86), B64 (87),
109 B64 (88), B64 (89), B64 (90), B64 (91),
110 B64 (92), B64 (93), B64 (94), B64 (95),
111 B64 (96), B64 (97), B64 (98), B64 (99),
112 B64 (100), B64 (101), B64 (102), B64 (103),
113 B64 (104), B64 (105), B64 (106), B64 (107),
114 B64 (108), B64 (109), B64 (110), B64 (111),
115 B64 (112), B64 (113), B64 (114), B64 (115),
116 B64 (116), B64 (117), B64 (118), B64 (119),
117 B64 (120), B64 (121), B64 (122), B64 (123),
118 B64 (124), B64 (125), B64 (126), B64 (127),
119 B64 (128), B64 (129), B64 (130), B64 (131),
120 B64 (132), B64 (133), B64 (134), B64 (135),
121 B64 (136), B64 (137), B64 (138), B64 (139),
122 B64 (140), B64 (141), B64 (142), B64 (143),
123 B64 (144), B64 (145), B64 (146), B64 (147),
124 B64 (148), B64 (149), B64 (150), B64 (151),
125 B64 (152), B64 (153), B64 (154), B64 (155),
126 B64 (156), B64 (157), B64 (158), B64 (159),
127 B64 (160), B64 (161), B64 (162), B64 (163),
128 B64 (164), B64 (165), B64 (166), B64 (167),
129 B64 (168), B64 (169), B64 (170), B64 (171),
130 B64 (172), B64 (173), B64 (174), B64 (175),
131 B64 (176), B64 (177), B64 (178), B64 (179),
132 B64 (180), B64 (181), B64 (182), B64 (183),
133 B64 (184), B64 (185), B64 (186), B64 (187),
134 B64 (188), B64 (189), B64 (190), B64 (191),
135 B64 (192), B64 (193), B64 (194), B64 (195),
136 B64 (196), B64 (197), B64 (198), B64 (199),
137 B64 (200), B64 (201), B64 (202), B64 (203),
138 B64 (204), B64 (205), B64 (206), B64 (207),
139 B64 (208), B64 (209), B64 (210), B64 (211),
140 B64 (212), B64 (213), B64 (214), B64 (215),
141 B64 (216), B64 (217), B64 (218), B64 (219),
142 B64 (220), B64 (221), B64 (222), B64 (223),
143 B64 (224), B64 (225), B64 (226), B64 (227),
144 B64 (228), B64 (229), B64 (230), B64 (231),
145 B64 (232), B64 (233), B64 (234), B64 (235),
146 B64 (236), B64 (237), B64 (238), B64 (239),
147 B64 (240), B64 (241), B64 (242), B64 (243),
148 B64 (244), B64 (245), B64 (246), B64 (247),
149 B64 (248), B64 (249), B64 (250), B64 (251),
150 B64 (252), B64 (253), B64 (254), B64 (255)
155 * encodes src of sz length storing the new length in len
157 char* base64_encode( size_t *len
, char *src
, size_t sz
)
165 c
= sz
* 4 / 3 + sz
% 3 + 2;
167 r
= malloc( c
* sizeof(char) );
170 pad
= ((sz
% 3) == 0) ? 0 : 3 - sz
% 3;
172 /* time to do the bulk work */
174 for (c
=0; c
<sz
; c
+=3) {
176 /* specification wants newline after every 76 characters */
177 if ((c
> 0) && ((c
/ 3 * 4) % 76 == 0))
182 n
+= (c
+1<sz
) ? (src
[c
+1] << 8) : 0; /* may be out of range */
183 n
+= (c
+2<sz
) ? (src
[c
+2] << 0) : 0; /* may be out of range */
185 /* ch[0-3] are 6 bits each */
186 ch
[0] = (n
>> 18) & 63;
187 ch
[1] = (n
>> 12) & 63;
188 ch
[2] = (n
>> 6) & 63;
189 ch
[3] = (n
>> 0) & 63;
192 r
[i
++] = cb64
[ ch
[0] ];
193 r
[i
++] = cb64
[ ch
[1] ];
194 r
[i
++] = cb64
[ ch
[2] ];
195 r
[i
++] = cb64
[ ch
[3] ];
198 for (c
=0; c
<pad
; c
++)
200 r
[i
] = '\0'; /* it'll be a valid string */
208 * decode the buffer, same syntax as base64_encode
210 #define dec_valid(inp) (cd64[(int)inp] == -1) ? 0 : 1
211 #define dec_ch(inp) cd64[(int)inp]
212 char* base64_decode( size_t *len
, char *src
, size_t sz
)
220 r
= malloc( c
* sizeof(char) );
222 /* create a clean version of the text */
224 dat
= malloc( sz
* sizeof(char) );
226 for (i
=0; i
<sz
; i
++) {
227 if (src
[i
] == '=') /* control padding */
229 if (dec_valid( src
[i
] )) /* only allow valid characters */
235 for (c
=0; c
<j
; c
+=4) {
237 /* process the input from base 64 */
238 n
= dec_ch( dat
[c
+0] ) << 18; /* guaranteed to be valid */
239 n
+= (c
+1<j
) ? (dec_ch( dat
[c
+1] ) << 12) : 0; /* check if inbounds */
240 n
+= (c
+2<j
) ? (dec_ch( dat
[c
+2] ) << 6) : 0;
241 n
+= (c
+3<j
) ? (dec_ch( dat
[c
+3] ) << 0) : 0;
243 /* convert the 24 bits of encoded data into 3 8 bit chunks */
244 r
[i
++] = (n
>> 16) & 255;
245 r
[i
++] = (n
>> 8) & 255;
246 r
[i
++] = (n
>> 0) & 255;
252 (*len
) = i
- pad
; /* must decount the padding */