Here's the one I'm using:

#include <stdint.h>
#include <stdlib.h>


static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
                                'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
                                'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
                                'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
                                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
                                'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                                'w', 'x', 'y', 'z', '0', '1', '2', '3',
                                '4', '5', '6', '7', '8', '9', '+', '/'};
static char *decoding_table = NULL;
static int mod_table[] = {0, 2, 1};


char *base64_encode(const unsigned char *data,
                    size_t input_length,
                    size_t *output_length) {

    *output_length = 4 * ((input_length + 2) / 3);

    char *encoded_data = malloc(*output_length);
    if (encoded_data == NULL) return NULL;

    for (int i = 0, j = 0; i < input_length;) {

        uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
        uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
        uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;

        uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;

        encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
        encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
        encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
        encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
    }

    for (int i = 0; i < mod_table[input_length % 3]; i++)
        encoded_data[*output_length - 1 - i] = '=';

    return encoded_data;
}


unsigned char *base64_decode(const char *data,
                             size_t input_length,
                             size_t *output_length) {

    if (decoding_table == NULL) build_decoding_table();

    if (input_length % 4 != 0) return NULL;

    *output_length = input_length / 4 * 3;
    if (data[input_length - 1] == '=') (*output_length)--;
    if (data[input_length - 2] == '=') (*output_length)--;

    unsigned char *decoded_data = malloc(*output_length);
    if (decoded_data == NULL) return NULL;

    for (int i = 0, j = 0; i < input_length;) {

        uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
        uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
        uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
        uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];

        uint32_t triple = (sextet_a << 3 * 6)
        + (sextet_b << 2 * 6)
        + (sextet_c << 1 * 6)
        + (sextet_d << 0 * 6);

        if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
        if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
        if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
    }

    return decoded_data;
}


void build_decoding_table() {

    decoding_table = malloc(256);

    for (int i = 0; i < 64; i++)
        decoding_table[(unsigned char) encoding_table[i]] = i;
}


void base64_cleanup() {
    free(decoding_table);
}

Keep in mind that this doesn't do any error-checking while decoding - non base 64 encoded data will get processed.

Answer from ryyst on Stack Overflow
Top answer
1 of 16
138

Here's the one I'm using:

#include <stdint.h>
#include <stdlib.h>


static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
                                'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
                                'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
                                'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
                                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
                                'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                                'w', 'x', 'y', 'z', '0', '1', '2', '3',
                                '4', '5', '6', '7', '8', '9', '+', '/'};
static char *decoding_table = NULL;
static int mod_table[] = {0, 2, 1};


char *base64_encode(const unsigned char *data,
                    size_t input_length,
                    size_t *output_length) {

    *output_length = 4 * ((input_length + 2) / 3);

    char *encoded_data = malloc(*output_length);
    if (encoded_data == NULL) return NULL;

    for (int i = 0, j = 0; i < input_length;) {

        uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
        uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
        uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;

        uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;

        encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
        encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
        encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
        encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
    }

    for (int i = 0; i < mod_table[input_length % 3]; i++)
        encoded_data[*output_length - 1 - i] = '=';

    return encoded_data;
}


unsigned char *base64_decode(const char *data,
                             size_t input_length,
                             size_t *output_length) {

    if (decoding_table == NULL) build_decoding_table();

    if (input_length % 4 != 0) return NULL;

    *output_length = input_length / 4 * 3;
    if (data[input_length - 1] == '=') (*output_length)--;
    if (data[input_length - 2] == '=') (*output_length)--;

    unsigned char *decoded_data = malloc(*output_length);
    if (decoded_data == NULL) return NULL;

    for (int i = 0, j = 0; i < input_length;) {

        uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
        uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
        uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
        uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];

        uint32_t triple = (sextet_a << 3 * 6)
        + (sextet_b << 2 * 6)
        + (sextet_c << 1 * 6)
        + (sextet_d << 0 * 6);

        if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
        if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
        if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
    }

    return decoded_data;
}


void build_decoding_table() {

    decoding_table = malloc(256);

    for (int i = 0; i < 64; i++)
        decoding_table[(unsigned char) encoding_table[i]] = i;
}


void base64_cleanup() {
    free(decoding_table);
}

Keep in mind that this doesn't do any error-checking while decoding - non base 64 encoded data will get processed.

2 of 16
126

I know this question is quite old, but I was getting confused by the amount of solutions provided - each one of them claiming to be faster and better. I put together a project on github to compare the base64 encoders and decoders: https://github.com/gaspardpetit/base64-benchmark/

At this point, I have not limited myself to C algorithms - if one implementation performs well in C++, it can easily be backported to C. Also tests were conducted using Visual Studio 2015. If somebody wants to update this answer with results from clang/gcc, be my guest.

FASTEST ENCODERS: The two fastest encoder implementations I found were Jouni Malinen's at http://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c and the Apache at https://github.com/apple-oss-distributions/apache1/blob/apache1-697/apache1/src/ap/ap_base64.c.

Here is the time (in microseconds) to encode 32K of data using the different algorithms I have tested up to now:

jounimalinen                25.1544
apache                      25.5309
NibbleAndAHalf              38.4165
internetsoftwareconsortium  48.2879
polfosol                    48.7955
wikibooks_org_c             51.9659
gnome                       74.8188
elegantdice                 118.899
libb64                      120.601
manuelmartinez              120.801
arduino                     126.262
daedalusalpha               126.473
CppCodec                    151.866
wikibooks_org_cpp           343.2
adp_gmbh                    381.523
LihO                        406.693
libcurl                     3246.39
user152949                  4828.21

(René Nyffenegger's solution, credited in another answer to this question, is listed here as adp_gmbh).

Here is the one from Jouni Malinen that I slightly modified to return a std::string:

/*
* Base64 encoding/decoding (RFC1341)
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/

// 2016-12-12 - Gaspard Petit : Slightly modified to return a std::string 
// instead of a buffer allocated with malloc.

#include <string>

static const unsigned char base64_table[65] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/**
* base64_encode - Base64 encode
* @src: Data to be encoded
* @len: Length of the data to be encoded
* @out_len: Pointer to output length variable, or %NULL if not used
* Returns: Allocated buffer of out_len bytes of encoded data,
* or empty string on failure
*/
std::string base64_encode(const unsigned char *src, size_t len)
{
    unsigned char *out, *pos;
    const unsigned char *end, *in;

    size_t olen;

    olen = 4*((len + 2) / 3); /* 3-byte blocks to 4-byte */

    if (olen < len)
        return std::string(); /* integer overflow */

    std::string outStr;
    outStr.resize(olen);
    out = (unsigned char*)&outStr[0];

    end = src + len;
    in = src;
    pos = out;
    while (end - in >= 3) {
        *pos++ = base64_table[in[0] >> 2];
        *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
        *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
        *pos++ = base64_table[in[2] & 0x3f];
        in += 3;
    }

    if (end - in) {
        *pos++ = base64_table[in[0] >> 2];
        if (end - in == 1) {
            *pos++ = base64_table[(in[0] & 0x03) << 4];
            *pos++ = '=';
        }
        else {
            *pos++ = base64_table[((in[0] & 0x03) << 4) |
                (in[1] >> 4)];
            *pos++ = base64_table[(in[1] & 0x0f) << 2];
        }
        *pos++ = '=';
    }

    return outStr;
}

FASTEST DECODERS: Here are the decoding results and I must admit that I am a bit surprised:

polfosol                    45.2335
wikibooks_org_c             74.7347
apache                      77.1438
libb64                      100.332
gnome                       114.511
manuelmartinez              126.579
elegantdice                 138.514
daedalusalpha               151.561
jounimalinen                206.163
arduino                     335.95
wikibooks_org_cpp           350.437
CppCodec                    526.187
internetsoftwareconsortium  862.833
libcurl                     1280.27
LihO                        1852.4
adp_gmbh                    1934.43
user152949                  5332.87

Polfosol's snippet from Base64 decode snippet in C++ is the fastest by a factor of almost 2x.

Here is the code for the sake of completeness:

static const int B64index[256] = { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62, 63, 62, 62, 63, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61,  0,  0,  0,  0,  0,  0,  0,  0,  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,  0,
0,  0,  0, 63,  0, 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 };

std::string b64decode(const void* data, const size_t len)
{
    unsigned char* p = (unsigned char*)data;
    int pad = len > 0 && (len % 4 || p[len - 1] == '=');
    const size_t L = ((len + 3) / 4 - pad) * 4;
    std::string str(L / 4 * 3 + pad, '\0');

    for (size_t i = 0, j = 0; i < L; i += 4)
    {
        int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
        str[j++] = n >> 16;
        str[j++] = n >> 8 & 0xFF;
        str[j++] = n & 0xFF;
    }
    if (pad)
    {
        int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12;
        str[str.size() - 1] = n >> 16;

        if (len > L + 2 && p[L + 2] != '=')
        {
            n |= B64index[p[L + 2]] << 6;
            str.push_back(n >> 8 & 0xFF);
        }
    }
    return str;
}
🌐
GitHub
github.com › elzoughby › Base64
GitHub - elzoughby/Base64: C library to encode and decode strings with base64 format · GitHub
Groups of 6 bits (6 bits have a ... numbers in a 24-bit string), which are then converted into their corresponding Base64 character values. ... This is a C library to encode ASCII string to base64 format and decode base64 string to ASCII....
Author: elzoughby
Discussions

b64 - A command-line Base64 encoder and decoder in C
I've had to write base 64 encoders and decoders in several languages because I actually needed them for larger projects, so you might be surprised when you say that it's not the most useful thing. Also, it's a great C-learning project. More on reddit.com
🌐 r/C_Programming
8
18
April 22, 2025
Wrote a simple base64 encoder/decoder and thought I'd share it.
glib is particularly complicated. You could also use e.g. the libb64 . Your code is good, but I recommend you to use a separate length argument as base64 allows for the encoding of NUL bytes. Your code is a bit strange in that it constantly reallocates buffers, which is a bit slow and unexpected. I'm not sure how to use your code as you do not tell the user anywhere how long the allocated data region is. More on reddit.com
🌐 r/C_Programming
14
7
March 31, 2017
There's unredacted attachments as base64 in some of the DOJ dumps. Anyone played this yet? (EFTA02609263)
u/Consistent-Hat-8008 please reply to this comment with submission statement. Your submission statement must explain why your post is relevant to the r/Epstein community. Posts without a submission statement after 30 minutes will be removed at the discretion of the moderators. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns. More on reddit.com
🌐 r/Epstein
40
111
February 2, 2026
Convert data to Base64 in Node.js
Fun fact - base64 encoding is about 40%-60% faster in the latest release of io.js. More on reddit.com
🌐 r/node
3
2
August 28, 2015
🌐
Leonardotamiano
blog.leonardotamiano.xyz › tech › base64
Base64 Encoder in C - Leonardo Tamiano
The specific mapping between characters and numbers can be analyzed in the original standardization of the encoding, which can be found in RFC4648. In linux we have the base64 binary which allows for encoding and decoding of arbitrary text.
🌐
MIT
web.mit.edu › freebsd › head › contrib › wpa › src › utils › base64.c
base64.c
*/ unsigned char * base64_decode(const unsigned char *src, size_t len, size_t *out_len) { unsigned char dtable[256], *out, *pos, block[4], tmp; size_t i, count, olen; int pad = 0; os_memset(dtable, 0x80, 256); for (i = 0; i < sizeof(base64_table) - 1; i++) dtable[base64_table[i]] = (unsigned char) i; dtable['='] = 0; count = 0; for (i = 0; i < len; i++) { if (dtable[src[i]] != 0x80) count++; } if (count == 0 || count % 4) return NULL; olen = count / 4 * 3; pos = out = os_malloc(olen); if (out == NULL) return NULL; count = 0; for (i = 0; i < len; i++) { tmp = dtable[src[i]]; if (tmp == 0x80) co
🌐
Lua Ternary
nachtimwald.com › posts › base64 encode and decode in c
Base64 Encode and Decode in C | John's Blog
November 18, 2017 - Finally, add the byte or an = for padding if there are less than 3 bytes in the last block. 1 and 2 fewer than 3 bytes gets 1 or 2 padding characters. Much like encoding, we need to do some math to determine binary data size of some Base64 encoded data we might have. size_t b64_decoded_size(const char *in) { size_t len; size_t ret; size_t i; if (in == NULL) return 0; len = strlen(in); ret = len / 4 * 3; for (i=len; i-->0; ) { if (in[i] == '=') { ret--; } else { break; } } return ret; }
🌐
Sampleprograms
sampleprograms.io › projects › base64-encode-decode › c
Base64 Encode Decode in C | Sample Programs in Every Language
July 28, 2025 - #include <ctype.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> static const unsigned char base64_alphabet[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static unsigned char *base64_encode(const unsigned char *input, size_t length, size_t *output_length); static unsigned char *base64_decode(const unsigned char *input, size_t length, size_t *output_length); static int is_valid_base64(const char *string); static void show_usage(void); int main(int argc, char *argv[]) { if (argc != 3) show_usage(); const char *mode = argv[1]; const cha
🌐
MYCPLUS
mycplus.com › home › programing source code examples › c programming source code examples
C Implementation of Base64 Encoding and Decoding - MYCPLUS
May 8, 2026 - This allows content creators or web developers to embed images or files inline in documents. Base64 data is generally url-safe, and that’s why it can be used to encode data in Data URLs. This is a very simple implementation of base64 encoding and decoding in C programming language.
Find elsewhere
🌐
GitHub
github.com › jwerle › b64.c
GitHub - jwerle/b64.c: Base64 encode/decode · GitHub
RFC 4648 Compliant Base64 encode/decode implementation ... #include <stdio.h> #include <string.h> #include <stdlib.h> #include "b64.h" int main (void) { unsigned char *str = "brian the monkey and bradley the kinkajou are friends"; char *enc = b64_encode(str, strlen(str)); printf("%s\n", enc); // YnJpYW4gdGhlIG1vbmtleSBhbmQgYnJhZGxleSB0aGUga2lua2Fqb3UgYXJlIGZyaWVuZHM= char *dec = b64_decode(enc, strlen(enc)); printf("%s\n", dec); // brian the monkey and bradley the kinkajou are friends free(enc); free(dec); return 0; }
Starred by 285 users
Forked by 104 users
Languages: C 93.4% | Makefile 3.7% | CMake 2.9%
🌐
Medium
medium.com › @js_9757 › revisiting-the-basics-implementing-base64-from-scratch-in-pure-c-c6985fb08420
Revisiting the Basics: Implementing Base64 from Scratch in pure C | by Jens@Fivesec | Medium
September 24, 2024 - At least two Base64 characters are required: the first provides 6 bits, and the second contributes its first 2 bits. *Shorted version from Wikipedia* All this information This will leed to following C implementation to decode a base64 encoded string:
🌐
Fm4dd
fm4dd.com › programming › base64 › base64_stringencode_c.shtm
base64_stringencode.c - tests encoding/decoding strings with base64 in 'C'
b64[ ((in[1] & 0x0f) &lt;< 2) | ((in[2] & 0xc0) &gt;> 6) ] : '='); out[3] = (unsigned char) (len > 2 ? b64[ in[2] & 0x3f ] : '='); out[4] = '\0'; strncat(b64str, out, sizeof(out)); } /* encode - base64 encode a stream, adding padding if needed */ void b64_encode(char *clrstr, char *b64dst) { unsigned char in[3]; int i, len = 0; int j = 0; b64dst[0] = '\0'; while(clrstr[j]) { len = 0; for(i=0; i<3; i++) { in[i] = (unsigned char) clrstr[j]; if(clrstr[j]) { len++; j++; } else in[i] = 0; } if( len ) { encodeblock( in, b64dst, len ); } } } int main() { //char mysrc[] = "My bonnie is over the ocean.
🌐
O'Reilly
oreilly.com › library › view › secure-programming-cookbook › 0596003943 › ch04s06.html
4.6. Performing Base64 Decoding - Secure Programming Cookbook for C and C++ [Book]
This is most easily done via table lookup, mapping each character in the input to six bits of output. Following is our code for decoding a base64-encoded string. We look at each byte separately, mapping it to its associated 6-bit value.
🌐
SourceForge
base64.sourceforge.net › b64.c
/\ MODULE NAME: b64.c AUTHOR: Bob Trower 2001/08/04
Non-zero is an error code.\n" ); printf( " ErrCode: 1 = Bad Syntax, 2 = File Open, 3 = File I/O\n" ); printf( " Example: b64 -e binfile b64file <- Encode to b64\n" ); printf( " b64 -d b64file binfile <- Decode from b64\n" ); printf( " b64 -e -l40 infile outfile <- Line Length of 40\n" ); printf( " Note: Will act as a filter, but this should only be\n" ); printf( " used on text files due to translations made by\n" ); printf( " operating systems.\n" ); printf( " Source: Source code and latest releases can be found at:\n" ); printf( " http://base64.sourceforge.net\n" ); printf( " Release: 0.94.00
🌐
IQ
iq.direct › home › blog › encode and decode base64 string in c
Encode and decode Base64 string in C
A simple C program to encode and decode Base64 strings without using any third-party libraries: #include <stdio.h> #include <string.h> const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; void encode_base64(char *input, char *output) { int i = 0, j = 0; unsigned char input_buffer[3], output_buffer[4]; while (input[i] != '\0') { int input_length = 0; for (int k = 0; k < 3; k++) { if (input[i] != '\0') { input_buffer[k] = input[i++]; input_length++; } else { input_buffer[k] = 0; } } output_buffer[0] = (input_buffer[0] & 0xFC) >> 2; output_buffer[1] = ((
🌐
Base64 Decode
base64decode.org › base64 decoder tool › base64 decoding articles › base64 decoding in c: a complete guide
Base64 Decoding in C: A Complete Guide
3 weeks ago - Build a C decoder with EVP_DecodeBlock and Mbed TLS: exact buffer math, the zero-padding trap, hand-made base64url, plus JWTs, files and PEM armor.
🌐
Cribl
docs.cribl.io › stream › expressions-encode-decode
C.Decode and C.Encode - Encoding and Decoding | Cribl Docs
Performs Base64 decoding of the given string. Returns a string or Buffer, depending on the resultEnc value. To decode an encoded field and return the decoded value as a Buffer, use: ... Gunzips the supplied value. To decode a hostname field which had been encoded using hex, run: ... Performs ...
🌐
Base64
base64.dev › home › articles › base64 in c
Base64 Encoding & Decoding in C — base64.dev
July 3, 2026 - C has no standard library function for Base64. You either implement it yourself using a lookup table or link against OpenSSL. Here is a complete, correct implementation plus the OpenSSL alternative.
🌐
Reddit
reddit.com › r/c_programming › wrote a simple base64 encoder/decoder and thought i'd share it.
r/C_Programming on Reddit: Wrote a simple base64 encoder/decoder and thought I'd share it.
March 31, 2017 -

So I needed to do some base64 encoding/decoding for a project I was working on and I was unsatisfied with the options I was finding. For the most part, people seemed to suggest using third party libraries that included base64 functions as part of a much larger set of tools (glib, for example), but I guess the purist in me wanted a simpler solution. So I ended up just writing my own encode/decode functions, and surprisingly it wasn't as complicated as I thought.

Still though, I am surprised at the lack of straight-forward solutions offered for C. Or did I just miss it somewhere? There are some projects on github but they are either poorly documented or seem unnecessarily complex. So I packaged up the functions I wrote, made the interface as dead-simple as possible, and put it on my github page for others who might also be searching for a solution:

base64-simple

Let me know if you think I missed a solution somewhere, or what you would have done for your base64 needs. Is using a library such a glib normal in this case? I'm also open to code critiques.

🌐
SourceForge
libb64.sourceforge.net
libb64: Base64 Encoding/Decoding Routines
libb64 is a library of ANSI C routines for fast encoding/decoding data into and from a base64-encoded format.