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