1 /*
2 * Output a base64 string.
3 *
4 * Options include:
5 * - Character 62 and 63;
6 * - To pad or not to pad.
7 */
8
9 #include <inttypes.h>
10 #include <base64.h>
11
genbase64(char * output,const void * input,size_t size,int flags)12 size_t genbase64(char *output, const void *input, size_t size, int flags)
13 {
14 static char charz[] =
15 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_";
16 uint8_t buf[3];
17 int j;
18 const uint8_t *p;
19 char *q;
20 uint32_t bv;
21 int left = size;
22
23 charz[62] = (char)flags;
24 charz[63] = (char)(flags >> 8);
25
26 p = input;
27 q = output;
28
29 while (left > 0) {
30 if (left < 3) {
31 buf[0] = p[0];
32 buf[1] = (left > 1) ? p[1] : 0;
33 buf[2] = 0;
34 p = buf;
35 }
36
37 bv = (p[0] << 16) | (p[1] << 8) | p[2];
38 p += 3;
39 left -= 3;
40
41 for (j = 0; j < 4; j++) {
42 *q++ = charz[(bv >> 18) & 0x3f];
43 bv <<= 6;
44 }
45 }
46
47 switch (left) {
48 case -1:
49 if (flags & BASE64_PAD)
50 q[-1] = '=';
51 else
52 q--;
53 break;
54
55 case -2:
56 if (flags & BASE64_PAD)
57 q[-2] = q[-1] = '=';
58 else
59 q -= 2;
60 break;
61
62 default:
63 break;
64 }
65
66 *q = '\0';
67
68 return q - output;
69 }
70
71 #ifdef TEST
72
73 #include <stdio.h>
74 #include <string.h>
75
main(int argc,char * argv[])76 int main(int argc, char *argv[])
77 {
78 int i;
79 char buf[4096];
80 int len, bytes;
81
82 for (i = 1; i < argc; i++) {
83 printf("Original: \"%s\"\n", argv[i]);
84
85 len = strlen(argv[i]);
86 bytes = genbase64(buf, argv[i], len, BASE64_MIME | BASE64_PAD);
87 printf(" MIME: \"%s\" (%d)\n", buf, bytes);
88 bytes = genbase64(buf, argv[i], len, BASE64_SAFE);
89 printf(" Safe: \"%s\" (%d)\n", buf, bytes);
90 }
91
92 return 0;
93 }
94
95 #endif
96