1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> static const char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char *b64_encode(const unsigned char *data, size_t input_len, size_t *output_len) { *output_len = 4 * ((input_len + 2) / 3); char *enc = (char *)malloc(*output_len + 1); if (enc == NULL) return NULL; size_t i, j; for (i = 0, j = 0; i < input_len; i += 3) { uint32_t a = i < input_len ? data[i] : 0; uint32_t b = (i + 1) < input_len ? data[i + 1] : 0; uint32_t c = (i + 2) < input_len ? data[i + 2] : 0; uint32_t hoge = (a << 16) | (b << 8) | c; enc[j++] = base64_table[(hoge >> 18) & 0x3F]; enc[j++] = base64_table[(hoge >> 12) & 0x3F]; enc[j++] = (i + 1) < input_len ? base64_table[(hoge >> 6) & 0x3F] : '='; enc[j++] = (i + 2) < input_len ? base64_table[hoge & 0x3F] : '='; } enc[*output_len] = '\0'; return enc; }
static int b64_value(char c) { if (c >= 'A' && c <= 'Z') return c - 'A'; if (c >= 'a' && c <= 'z') return c - 'a' + 26; if (c >= '0' && c <= '9') return c - '0' + 52; if (c == '+') return 62; if (c == '/') return 63; if (c == '=') return 0; return -1; }
unsigned char *b64_decode(const char *data, size_t input_len, size_t *output_len) { if (input_len % 4 != 0) { return NULL; } size_t padding = 0; if (input_len > 0) { if (data[input_len - 1] == '=') padding++; if (data[input_len - 2] == '=') padding++; } *output_len = (input_len * 3) / 4 - padding; unsigned char *dec = (unsigned char *)malloc(*output_len); if (dec == NULL) return NULL; size_t i, j; for (i = 0, j = 0; i < input_len; i += 4) { int a = b64_value(data[i]); int b = b64_value(data[i + 1]); int c = b64_value(data[i + 2]); int d = b64_value(data[i + 3]); if (a == -1 || b == -1 || c == -1 || d == -1) { free(dec); return NULL; } uint32_t hoge = (a << 18) | (b << 12) | (c << 6) | d; if (j < *output_len) dec[j++] = (hoge >> 16) & 0xFF; if (j < *output_len) dec[j++] = (hoge >> 8) & 0xFF; if (j < *output_len) dec[j++] = hoge & 0xFF; } return dec; }
int main() { const char *test = "re100dayzhuji"; size_t len = strlen(test); size_t eln, dln; char *enc = b64_encode((const unsigned char *)test, len, &eln); printf("encoded: %s\n", enc); unsigned char *dec = b64_decode(enc, eln, &dln); printf("decoded: %.*s\n", (int)dln, dec); free(enc); free(dec); system("pause"); return 0; }
|