1 | /*␊ |
2 | * This code implements the BASE64 algorithm.␊ |
3 | * This code is in the public domain; do with it what you wish.␊ |
4 | *␊ |
5 | * @file base64.c␊ |
6 | * @brief This code implements the BASE64 algorithm␊ |
7 | * @author Matthieu Speder␊ |
8 | */␊ |
9 | #include <libsaio.h>␊ |
10 | ␊ |
11 | //static const char base64_chars[] =␊ |
12 | //"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";␊ |
13 | ␊ |
14 | static const char base64_digits[] =␊ |
15 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,␊ |
16 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,␊ |
17 | 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,␊ |
18 | 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,␊ |
19 | 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26,␊ |
20 | 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,␊ |
21 | 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,␊ |
22 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,␊ |
23 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,␊ |
24 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,␊ |
25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,␊ |
26 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };␊ |
27 | ␊ |
28 | ␊ |
29 | char *BASE64Decode(const char* src, int in_len, int* out_len)␊ |
30 | {␊ |
31 | int endpad = 0;␊ |
32 | char* dest;␊ |
33 | char* result;␊ |
34 | ␊ |
35 | if (in_len % 4)␊ |
36 | {␊ |
37 | /* Wrong base64 string length */␊ |
38 | return NULL;␊ |
39 | }␊ |
40 | result = dest = malloc(in_len / 4 * 3 + 1);␊ |
41 | if (result == NULL)␊ |
42 | return NULL; /* out of memory */␊ |
43 | while (*src) {␊ |
44 | char a = base64_digits[(unsigned char)*(src++)];␊ |
45 | char b = base64_digits[(unsigned char)*(src++)];␊ |
46 | char c = base64_digits[(unsigned char)*(src++)];␊ |
47 | char d = base64_digits[(unsigned char)*(src++)];␊ |
48 | *(dest++) = (a << 2) | ((b & 0x30) >> 4);␊ |
49 | if (c == (char)-1)␊ |
50 | {␊ |
51 | // padding char.␊ |
52 | endpad += 2;␊ |
53 | break;␊ |
54 | }␊ |
55 | *(dest++) = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2);␊ |
56 | if (d == (char)-1)␊ |
57 | {␊ |
58 | // padding char.␊ |
59 | endpad += 1;␊ |
60 | break;␊ |
61 | }␊ |
62 | *(dest++) = ((c & 0x03) << 6) | d;␊ |
63 | }␊ |
64 | *dest = 0;␊ |
65 | *out_len = in_len / 4 * 3 - endpad; // not including NULL terminator␊ |
66 | return result;␊ |
67 | }␊ |
68 | ␊ |
69 | ␊ |
70 | /* end of base64.c */␊ |
71 | |