Home | History | Annotate | Download | only in libutil
      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 
     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 
     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