]> pd.if.org Git - zpackage/blob - crypto/base64.c
add missing file
[zpackage] / crypto / base64.c
1 #define _POSIX_C_SOURCE 200809L
2
3 #include <stdint.h>
4 #include <stdlib.h>
5
6 #define WHITESPACE 64
7 #define EQUALS     65
8 #define INVALID    66
9
10 static const unsigned char d[] = {
11         66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 66, 66, 66, 66,
12             66, 66, 66, 66, 66, 66, 66, 66,
13         66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
14             66, 62, 66, 66, 66, 63, 52, 53,
15         54, 55, 56, 57, 58, 59, 60, 61, 66, 66, 66, 65, 66, 66, 66, 0, 1,
16             2, 3, 4, 5, 6, 7, 8, 9,
17         10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 66,
18             66, 66, 66, 66, 66, 26, 27, 28,
19         29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
20             46, 47, 48, 49, 50, 51, 66, 66,
21         66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
22             66, 66, 66, 66, 66, 66, 66, 66,
23         66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
24             66, 66, 66, 66, 66, 66, 66, 66,
25         66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
26             66, 66, 66, 66, 66, 66, 66, 66,
27         66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
28             66, 66, 66, 66, 66, 66, 66, 66,
29         66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
30             66, 66, 66, 66, 66, 66, 66, 66,
31         66, 66, 66, 66, 66, 66
32 };
33
34 int base64decode(const char *in, size_t inLen, unsigned char *out,
35                  size_t *outLen) {
36         const char *end = in + inLen;
37         char iter = 0;
38         uint32_t buf = 0;
39         size_t len = 0;
40
41         while (in < end) {
42                 unsigned char c = d[(int)(*in++)];
43
44                 switch (c) {
45                 case WHITESPACE:
46                         continue;       /* skip whitespace */
47                 case INVALID:
48                         return 0;       /* invalid input, return error */
49                 case EQUALS:    /* pad character, end of data */
50                         in = end;
51                         continue;
52                 default:
53                         buf = buf << 6 | c;
54                         iter++; // increment the number of iteration
55                         /* If the buffer is full, split it into bytes */
56                         if (iter == 4) {
57                                 if ((len += 3) > *outLen)
58                                         return 0;       /* buffer overflow */
59                                 *(out++) = (buf >> 16) & 255;
60                                 *(out++) = (buf >> 8) & 255;
61                                 *(out++) = buf & 255;
62                                 buf = 0;
63                                 iter = 0;
64
65                         }
66                 }
67         }
68
69         if (iter == 3) {
70                 if ((len += 2) > *outLen)
71                         return 0;       /* buffer overflow */
72                 *(out++) = (buf >> 10) & 255;
73                 *(out++) = (buf >> 2) & 255;
74         } else if (iter == 2) {
75                 if (++len > *outLen)
76                         return 0;       /* buffer overflow */
77                 *(out++) = (buf >> 4) & 255;
78         }
79
80         *outLen = len;          /* modify to reflect the actual output size */
81         return 1;
82 }