diff options
Diffstat (limited to 'src/base64.c')
| -rw-r--r-- | src/base64.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/base64.c b/src/base64.c new file mode 100644 index 0000000..066494e --- /dev/null +++ b/src/base64.c | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | /* | ||
| 2 | * base64.c | ||
| 3 | * base64 encode/decode implementation | ||
| 4 | * | ||
| 5 | * Copyright (c) 2011 Nikias Bassen, All Rights Reserved. | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | #include <string.h> | ||
| 22 | #include "base64.h" | ||
| 23 | |||
| 24 | static const char base64_str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
| 25 | static const char base64_pad = '='; | ||
| 26 | |||
| 27 | static const int8_t base64_table[256] = { | ||
| 28 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 29 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 30 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, | ||
| 31 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, | ||
| 32 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, | ||
| 33 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, | ||
| 34 | -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, | ||
| 35 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, | ||
| 36 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 38 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 39 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 40 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 41 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 42 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 43 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 | ||
| 44 | }; | ||
| 45 | |||
| 46 | char *base64encode(const unsigned char *buf, size_t *size) | ||
| 47 | { | ||
| 48 | if (!buf || !size || !(*size > 0)) return NULL; | ||
| 49 | int outlen = (*size / 3) * 4; | ||
| 50 | char *outbuf = (char*)malloc(outlen+5); // 4 spare bytes + 1 for '\0' | ||
| 51 | size_t n = 0; | ||
| 52 | size_t m = 0; | ||
| 53 | unsigned char input[3]; | ||
| 54 | unsigned int output[4]; | ||
| 55 | while (n < *size) { | ||
| 56 | input[0] = buf[n++]; | ||
| 57 | input[1] = (n < *size) ? buf[n++] : 0; | ||
| 58 | input[2] = (n < *size) ? buf[n++] : 0; | ||
| 59 | output[0] = input[0] >> 2; | ||
| 60 | output[1] = ((input[0] & 3) << 4) + (input[1] >> 4); | ||
| 61 | output[2] = ((input[1] & 15) << 2) + (input[2] >> 6); | ||
| 62 | output[3] = input[2] & 63; | ||
| 63 | outbuf[m++] = base64_str[(int)output[0]]; | ||
| 64 | outbuf[m++] = base64_str[(int)output[1]]; | ||
| 65 | outbuf[m++] = base64_str[(int)output[2]]; | ||
| 66 | outbuf[m++] = base64_str[(int)output[3]]; | ||
| 67 | } | ||
| 68 | while ((m % 4) != 0) { | ||
| 69 | outbuf[m++] = base64_pad; | ||
| 70 | } | ||
| 71 | outbuf[m] = 0; // 0-termination! | ||
| 72 | *size = m; | ||
| 73 | return outbuf; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int base64decode_block(unsigned char *target, const char *data, size_t data_size) | ||
| 77 | { | ||
| 78 | int w1,w2,w3,w4; | ||
| 79 | int n,i; | ||
| 80 | |||
| 81 | if (!data || (data_size <= 0)) { | ||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 85 | n = 0; | ||
| 86 | i = 0; | ||
| 87 | while (n < data_size-3) { | ||
| 88 | w1 = base64_table[(int)data[n]]; | ||
| 89 | w2 = base64_table[(int)data[n+1]]; | ||
| 90 | w3 = base64_table[(int)data[n+2]]; | ||
| 91 | w4 = base64_table[(int)data[n+3]]; | ||
| 92 | |||
| 93 | if (w2 >= 0) { | ||
| 94 | target[i++] = (char)((w1*4 + (w2 >> 4)) & 255); | ||
| 95 | } | ||
| 96 | if (w3 >= 0) { | ||
| 97 | target[i++] = (char)((w2*16 + (w3 >> 2)) & 255); | ||
| 98 | } | ||
| 99 | if (w4 >= 0) { | ||
| 100 | target[i++] = (char)((w3*64 + w4) & 255); | ||
| 101 | } | ||
| 102 | n+=4; | ||
| 103 | } | ||
| 104 | return i; | ||
| 105 | } | ||
| 106 | |||
| 107 | unsigned char *base64decode(const char *buf, size_t *size) | ||
| 108 | { | ||
| 109 | if (!buf) return; | ||
| 110 | size_t len = strlen(buf); | ||
| 111 | if (len <= 0) return; | ||
| 112 | unsigned char *outbuf = (unsigned char*)malloc((len/4)*3+3); | ||
| 113 | |||
| 114 | unsigned char *line; | ||
| 115 | int p = 0; | ||
| 116 | |||
| 117 | line = (unsigned char*)strtok((char*)buf, "\r\n\t "); | ||
| 118 | while (line) { | ||
| 119 | p+=base64decode_block(outbuf+p, line, strlen((char*)line)); | ||
| 120 | |||
| 121 | // get next line of base64 encoded block | ||
| 122 | line = (unsigned char*)strtok(NULL, "\r\n\t "); | ||
| 123 | } | ||
| 124 | outbuf[p] = 0; | ||
| 125 | *size = p; | ||
| 126 | return outbuf; | ||
| 127 | } | ||
