Base64 Encoding in C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>

char *base64_encode(const unsigned char *input, int length) {
    BIO *bmem, *b64;
    BUF_MEM *bptr;

    b64 = BIO_new(BIO_f_base64());
    bmem = BIO_new(BIO_s_mem());
    b64 = BIO_push(b64, bmem);
    BIO_write(b64, input, length);
    BIO_flush(b64);
    BIO_get_mem_ptr(b64, &bptr);

    char *buff = (char *)malloc(bptr->length);
    memcpy(buff, bptr->data, bptr->length-1);
    buff[bptr->length-1] = 0;

    BIO_free_all(b64);

    return buff;
}

char *base64_decode(const char *input, int length, int *output_length) {
    BIO *b64, *bmem;

    char *buffer = (char *)malloc(length);
    memset(buffer, 0, length);

    b64 = BIO_new(BIO_f_base64());
    bmem = BIO_new_mem_buf(input, length);
    bmem = BIO_push(b64, bmem);

    *output_length = BIO_read(bmem, buffer, length);

    BIO_free_all(bmem);

    return buffer;
}

int main() {
    const char *data = "abc123!?$*&()'-=@~";

    // Standard base64 encoding
    char *sEnc = base64_encode((const unsigned char *)data, strlen(data));
    printf("Standard encoding: %s\n", sEnc);

    // Standard base64 decoding
    int decoded_len;
    char *sDec = base64_decode(sEnc, strlen(sEnc), &decoded_len);
    printf("Standard decoding: %.*s\n\n", decoded_len, sDec);

    // URL-safe base64 encoding (Note: C doesn't have a built-in URL-safe base64 encoder)
    // For demonstration, we'll use the standard encoder and manually replace characters
    char *uEnc = strdup(sEnc);
    for (int i = 0; uEnc[i]; i++) {
        if (uEnc[i] == '+') uEnc[i] = '-';
        if (uEnc[i] == '/') uEnc[i] = '_';
    }
    printf("URL-safe encoding: %s\n", uEnc);

    // URL-safe base64 decoding
    for (int i = 0; uEnc[i]; i++) {
        if (uEnc[i] == '-') uEnc[i] = '+';
        if (uEnc[i] == '_') uEnc[i] = '/';
    }
    char *uDec = base64_decode(uEnc, strlen(uEnc), &decoded_len);
    printf("URL-safe decoding: %.*s\n", decoded_len, uDec);

    free(sEnc);
    free(sDec);
    free(uEnc);
    free(uDec);

    return 0;
}

This C program demonstrates base64 encoding and decoding. It uses the OpenSSL library to perform the base64 operations.

Here’s a breakdown of the code:

  1. We include necessary headers, including OpenSSL headers for base64 operations.

  2. We define two helper functions:

    • base64_encode: Encodes a string to base64.
    • base64_decode: Decodes a base64 string.
  3. In the main function:

    • We define our input string.
    • We perform standard base64 encoding and decoding.
    • We demonstrate URL-safe base64 encoding by manually replacing ‘+’ with ‘-’ and ‘/’ with ‘_’.
    • We demonstrate URL-safe base64 decoding by reversing the character replacements and then decoding.
  4. We print the results of each operation.

  5. Finally, we free the allocated memory.

Note that C doesn’t have built-in support for base64 encoding/decoding, so we’re using the OpenSSL library. Also, C doesn’t have a built-in URL-safe base64 encoder, so we’re manually adjusting the standard encoded string for demonstration purposes.

To compile and run this program, you’ll need to have OpenSSL installed and link against it:

$ gcc -o base64_example base64_example.c -lssl -lcrypto
$ ./base64_example
Standard encoding: YWJjMTIzIT8kKiYoKSctPUB+
Standard decoding: abc123!?$*&()'-=@~

URL-safe encoding: YWJjMTIzIT8kKiYoKSctPUB-
URL-safe decoding: abc123!?$*&()'-=@~

The output shows that both standard and URL-safe base64 encoding/decoding work as expected, producing the original string after decoding.