1 /************************************************************************
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
26 static const char* b64_chars
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
28 /* encode three bytes using base64 */
29 static void s_base64_encode_triple(unsigned char triple
[3], unsigned char result
[4])
35 tripleValue
= triple
[0];
37 tripleValue
+= triple
[1];
39 tripleValue
+= triple
[2];
49 result
[3-i
] = b64_chars
[v
];
55 /* get the value of a base64 encoding character */
56 static int s_base64_char_value(unsigned char c
)
58 if (c
>= 'A' && c
<= 'Z')
60 if (c
>= 'a' && c
<= 'z')
62 if (c
>= '0' && c
<= '9')
71 /* decode a 4 char base64 encoded byte triple */
72 static int s_base64_decode_triple(unsigned char quadruple
[4], unsigned char *result
)
74 int i
, triple_value
, bytes_to_decode
= 3, only_equals_yet
= 1;
78 char_value
[i
] = s_base64_char_value(quadruple
[i
]);
81 /* check if the characters are valid */
82 for (i
=3; i
>=0; i
--) {
83 if (char_value
[i
]<0) {
84 if (only_equals_yet
&& quadruple
[i
]=='=') {
85 /* we will ignore this character anyway, make it something
86 * that does not break our calculations */
93 /* after we got a real character, no other '=' are allowed anymore */
97 /* if we got "====" as input, bytes_to_decode is -1 */
98 if (bytes_to_decode
< 0)
101 /* make one big value out of the partial values */
102 triple_value
= char_value
[0];
104 triple_value
+= char_value
[1];
106 triple_value
+= char_value
[2];
108 triple_value
+= char_value
[3];
110 /* break the big value into bytes */
111 for (i
=bytes_to_decode
; i
<3; i
++) {
115 for (i
=bytes_to_decode
-1; i
>=0; i
--) {
116 result
[i
] = triple_value
%256;
120 return bytes_to_decode
;
123 /* encode an array of bytes using base64 */
124 int base64_lencode(char *source
, size_t sourcelen
, char *target
, size_t targetlen
)
126 /* check if the result will fit in the target buffer */
127 if ((sourcelen
+2)/3*4 > targetlen
-1)
130 /* encode all full triples */
131 while (sourcelen
>= 3) {
132 s_base64_encode_triple((unsigned char*)source
, (unsigned char*)target
);
138 /* encode the last one or two characters */
140 unsigned char temp
[3];
141 memset(temp
, 0, sizeof(temp
));
142 memcpy(temp
, source
, sourcelen
);
143 s_base64_encode_triple((unsigned char*)temp
, (unsigned char*)target
);
151 /* terminate the string */
157 /* decode base64 encoded data */
158 size_t base64_ldecode(char *source
, char *target
, size_t targetlen
)
161 char quadruple
[4], tmpresult
[3];
163 size_t converted
= 0;
165 /* concatinate '===' to the source to handle unpadded base64 data */
166 src
= (char *)malloc(strlen(source
)+5);
173 /* convert as long as we get a full result */
174 while (tmplen
== 3) {
175 /* get 4 characters to convert */
176 for (i
=0; i
<4; i
++) {
177 /* skip invalid characters - we won't reach the end */
178 while (*tmpptr
!= '=' && s_base64_char_value(*tmpptr
)<0) {
182 quadruple
[i
] = *(tmpptr
++);
185 /* convert the characters */
186 tmplen
= s_base64_decode_triple((unsigned char*)quadruple
, (unsigned char*)tmpresult
);
188 /* check if the fit in the result buffer */
189 if (targetlen
< tmplen
) {
194 /* put the partial result in the result buffer */
195 memcpy(target
, tmpresult
, tmplen
);