diff options
author | June McEnroe <june@causal.agency> | 2020-04-16 20:48:22 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2020-04-16 20:48:22 -0400 |
commit | f1fbffe76d68cc3e10f4be8cdc2ebba0cef46529 (patch) | |
tree | 05846df9521f425bea6e0c8385c9559a6d5ab04e | |
parent | Decode quoted-printable and 7bit/8bit (diff) | |
download | bubger-f1fbffe76d68cc3e10f4be8cdc2ebba0cef46529.tar.gz bubger-f1fbffe76d68cc3e10f4be8cdc2ebba0cef46529.zip |
Decode base64
Diffstat (limited to '')
-rw-r--r-- | decode.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/decode.c b/decode.c index abee7f5..a106c9c 100644 --- a/decode.c +++ b/decode.c @@ -17,6 +17,7 @@ #include <err.h> #include <errno.h> #include <iconv.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -85,6 +86,28 @@ static void convertCharset( iconv_close(conv); } +static uint8_t unbase64(char ch) { + static const char Base64[64] = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + }; + const char *ptr = strchr(Base64, ch); + return (ptr ? ptr - Base64 : 0); +} + +static void decodeBase64(struct Buffer *dst, const char *src) { + while (src[0] && src[1] && src[2] && src[3]) { + uint32_t bits = 0; + for (int i = 0; i < 4; ++i) { + bits <<= 6; + bits |= unbase64(src[i]); + } + *bufferDest(dst, 1) = bits >> 16; + if (src[2] != '=') *bufferDest(dst, 1) = bits >> 8; + if (src[3] != '=') *bufferDest(dst, 1) = bits; + src += 4; + } +} + static char unhex(char ch) { if (ch <= '9') return ch - '0'; if (ch <= 'F') return 0xA + ch - 'A'; @@ -149,7 +172,9 @@ static void decode8Bit(struct Buffer *dst, const char *src) { static void decodeEncoding(struct Buffer *dst, const char *encoding, const char *src) { - if (!strcasecmp(encoding, "Q")) { + if (!strcasecmp(encoding, "base64") || !strcasecmp(encoding, "B")) { + decodeBase64(dst, src); + } else if (!strcasecmp(encoding, "Q")) { decodeQ(dst, src); } else if (!strcasecmp(encoding, "quoted-printable")) { decodeQuotedPrintable(dst, src); |