Add support for Unix-standard MD5 password
[profile/ivi/syslinux.git] / com32 / libutil / base64.c
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;  q = output;
27
28   while (left > 0) {
29     if (left < 3) {
30       buf[0] = p[0];
31       buf[1] = (left > 1) ? p[1] : 0;
32       buf[2] = 0;
33       p = buf;
34     }
35
36     bv = (p[0] << 16) | (p[1] << 8) | p[2];
37     p += 3;
38     left -= 3;
39
40     for ( j = 0 ; j < 4 ; j++ ) {
41       *q++ = charz[(bv >> 18) & 0x3f];
42       bv <<= 6;
43     }
44   }
45
46   switch (left) {
47   case -1:
48     if (flags & BASE64_PAD)
49       q[-1] = '=';
50     else
51       q--;
52     break;
53
54   case -2:
55     if (flags & BASE64_PAD)
56       q[-2] = q[-1] = '=';
57     else
58       q -= 2;
59     break;
60
61   default:
62     break;
63   }
64
65   *q = '\0';
66
67   return q-output;
68 }
69
70 #ifdef TEST
71
72 #include <stdio.h>
73 #include <string.h>
74
75 int main(int argc, char *argv[])
76 {
77   int i;
78   char buf[4096];
79   int len, bytes;
80
81   for (i = 1; i < argc; i++) {
82     printf("Original: \"%s\"\n", argv[i]);
83
84     len = strlen(argv[i]);
85     bytes = genbase64(buf, argv[i], len, BASE64_MIME|BASE64_PAD);
86     printf("    MIME: \"%s\" (%d)\n", buf, bytes);
87     bytes = genbase64(buf, argv[i], len, BASE64_SAFE);
88     printf("    Safe: \"%s\" (%d)\n", buf, bytes);
89   }
90
91   return 0;
92 }
93
94 #endif
95