Branch data Line data Source code
1 : : #include "base64.h"
2 : :
3 : : static const char B64_CHARS[] =
4 : : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
5 : :
6 : 9 : void base64_encode(const unsigned char *in, size_t in_len, char *out) {
7 : 9 : size_t i = 0, j = 0;
8 : :
9 [ + + ]: 19 : while (i + 2 < in_len) {
10 : 10 : out[j++] = B64_CHARS[(in[i] >> 2)];
11 : 10 : out[j++] = B64_CHARS[(in[i] & 0x03) << 4 | (in[i+1] >> 4)];
12 : 10 : out[j++] = B64_CHARS[(in[i+1] & 0x0F) << 2 | (in[i+2] >> 6)];
13 : 10 : out[j++] = B64_CHARS[(in[i+2] & 0x3F)];
14 : 10 : i += 3;
15 : : }
16 : :
17 [ + + ]: 9 : if (i < in_len) {
18 : 6 : out[j++] = B64_CHARS[(in[i] >> 2)];
19 [ + + ]: 6 : if (i + 1 < in_len) {
20 : 4 : out[j++] = B64_CHARS[(in[i] & 0x03) << 4 | (in[i+1] >> 4)];
21 : 4 : out[j++] = B64_CHARS[(in[i+1] & 0x0F) << 2];
22 : : } else {
23 : 2 : out[j++] = B64_CHARS[(in[i] & 0x03) << 4];
24 : 2 : out[j++] = '=';
25 : : }
26 : 6 : out[j++] = '=';
27 : : }
28 : :
29 : 9 : out[j] = '\0';
30 : 9 : }
31 : :
32 : 68 : static int b64_val(char c) {
33 [ + + + + ]: 68 : if (c >= 'A' && c <= 'Z') return c - 'A';
34 [ + + + - ]: 47 : if (c >= 'a' && c <= 'z') return c - 'a' + 26;
35 [ + + + + ]: 21 : if (c >= '0' && c <= '9') return c - '0' + 52;
36 [ - + ]: 9 : if (c == '+') return 62;
37 [ - + ]: 9 : if (c == '/') return 63;
38 [ + + ]: 9 : if (c == '=') return 0;
39 : 1 : return -1;
40 : : }
41 : :
42 : 11 : int base64_decode(const char *in, size_t in_len, unsigned char *out) {
43 [ + + ]: 11 : if (in_len % 4 != 0) return -1;
44 : :
45 : 10 : int out_len = 0;
46 : :
47 [ + + ]: 26 : for (size_t i = 0; i < in_len; i += 4) {
48 : 17 : int a = b64_val(in[i]);
49 : 17 : int b = b64_val(in[i+1]);
50 : 17 : int c = b64_val(in[i+2]);
51 : 17 : int d = b64_val(in[i+3]);
52 : :
53 [ + - + - : 17 : if (a < 0 || b < 0 || c < 0 || d < 0) return -1;
+ + - + ]
54 : :
55 : 16 : out[out_len++] = (a << 2) | (b >> 4);
56 [ + + ]: 16 : if (in[i+2] != '=') out[out_len++] = (b << 4) | (c >> 2);
57 [ + + ]: 16 : if (in[i+3] != '=') out[out_len++] = (c << 6) | d;
58 : : }
59 : :
60 : 9 : return out_len;
61 : : }
|