3 Copyright (C) 2003 Elwood C. Downey
5 Complete rewrite of
to64frombits() - gives 2x the performance
7 Keeping
from64tobits() for compatibility - gives 2.5x the performance
8 of the old implementation (Aug, 2016 by Rumen G.Bogdanovski)
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2.1 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT
ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 Adapted from code written by Eric S. Raymond <esr@snark.thyrsus.com>
48 #define bswap_16(x) ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
51 #define IS_BIG_ENDIAN (!*(unsigned char *)&(uint16_t){1})
53 #include <arpa/inet.h>
54 #define IS_BIG_ENDIAN (1 == htons(1))
57 #define IS_LITTLE_ENDIAN (!IS_BIG_ENDIAN)
63 int to64frombits_s(
unsigned char *out,
const unsigned char *in,
int inlen,
size_t outlen)
65 size_t dlen = (((size_t)inlen + 2) / 3) * 4;
71 #pragma GCC diagnostic push
72 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
74 #pragma GCC diagnostic pop
77 int to64frombits(
unsigned char *out,
const unsigned char *in,
int inlen)
79 uint16_t *b64lut = (uint16_t *)base64lut;
80 int dlen = ((inlen + 2) / 3) * 4;
81 uint16_t *wbuf = (uint16_t *)out;
83 for (; inlen > 2; inlen -= 3)
85 uint32_t n = in[0] << 16 | in[1] << 8 | in[2];
87 wbuf[0] = b64lut[n >> 12];
88 wbuf[1] = b64lut[n & 0x00000fff];
94 out = (
unsigned char *)wbuf;
97 unsigned char fragment;
98 *out++ = base64digits[in[0] >> 2];
99 fragment = (in[0] << 4) & 0x30;
101 fragment |= in[1] >> 4;
102 *out++ = base64digits[fragment];
103 *out++ = (inlen < 2) ?
'=' : base64digits[(in[1] << 2) & 0x3c];
116 char *cp = (
char *)in;
129 int n = (inlen / 4) - 1;
130 uint16_t *inp = (uint16_t *)in;
132 for (j = 0; j < n; j++)
136 inp = (uint16_t *)in;
142 s1 = rbase64lut[inp[0]];
143 s2 = rbase64lut[inp[1]];
162 outlen = (inlen / 4 - 1) * 3;
165 inp = (uint16_t *)in;
171 s1 = rbase64lut[inp[0]];
172 s2 = rbase64lut[inp[1]];
186 if ((inp[1] & 0x00FF) != 0x003D)
190 if ((inp[1] & 0xFF00) != 0x3D00)
206 int n = (inlen / 4) - 1;
207 uint16_t *inp = (uint16_t *)in;
209 for (j = 0; j < n; j++)
213 inp = (uint16_t *)in;
215 s1 = rbase64lut[inp[0]];
216 s2 = rbase64lut[inp[1]];
235 outlen = (inlen / 4 - 1) * 3;
238 inp = (uint16_t *)in;
240 s1 = rbase64lut[inp[0]];
241 s2 = rbase64lut[inp[1]];
255 if ((inp[1] & 0x00FF) != 0x003D)
259 if ((inp[1] & 0xFF00) != 0x3D00)
269 #ifdef BASE64_PROGRAM
278 static void usage(
char *me)
280 fprintf(stderr,
"Purpose: convert stdin to/from base64 on stdout\n");
281 fprintf(stderr,
"Usage: %s {-t,-f}\n", me);
285 int main(
int ac,
char *av[])
290 if (ac == 2 && strcmp(av[1],
"-f") == 0)
292 else if (ac != 1 && (ac != 2 || strcmp(av[1],
"-t")))
297 unsigned char *rawin, *b64;
298 int i, n, nrawin, nb64;
301 rawin = malloc(4096);
303 while ((n = fread(rawin + nrawin, 1, 4096, stdin)) > 0)
304 rawin = realloc(rawin, (nrawin += n) + 4096);
307 b64 = malloc(4 * nrawin / 3 + 4);
311 size_t towrite = nb64;
312 while (written < nb64)
314 size_t wr = fwrite(b64 + written, 1, nb64, stdout);
324 unsigned char *raw, *b64;
330 while ((n = fread(b64 + nb64, 1, 4096, stdin)) > 0)
331 b64 = realloc(b64, (nb64 += n) + 4096);
335 raw = malloc(3 * nb64 / 4);
339 fprintf(stderr,
"base64 conversion error: %d\n", nraw);
344 fwrite(raw, 1, nraw, stdout);
361 int main(
int ac,
char *av[])
363 unsigned char *rawin, *b64, *rawback;
364 int n, nrawin, nrawback, nb64;
367 rawin = malloc(4096);
369 while ((n = fread(rawin + nrawin, 1, 4096, stdin)) > 0)
370 rawin = realloc(rawin, (nrawin += n) + 4096);
373 b64 = malloc(4 * nrawin * 3 + 4);
377 rawback = malloc(3 * nb64 / 4);
381 fprintf(stderr,
"base64 error: %d\n", nrawback);
384 if (nrawback != nrawin)
386 fprintf(stderr,
"base64 back length %d != %d\n", nrawback, nrawin);
391 if (memcmp(rawback, rawin, nrawin))
393 fprintf(stderr,
"compare error\n");
int from64tobits(char *out, const char *in)
Convert base64 to bytes array.
int to64frombits_s(unsigned char *out, const unsigned char *in, int inlen, size_t outlen)
Convert bytes array to base64.
int to64frombits(unsigned char *out, const unsigned char *in, int inlen)
int from64tobits_fast_with_bug(char *out, const char *in, int inlen)
int from64tobits_fast(char *out, const char *in, int inlen)
Namespace to encapsulate INDI client, drivers, and mediator classes.