0

$USD

$USD
TUTORIALS ESP32

ESP32 Arduino Tutorial: 34. Base64 decoding

DFRobot Feb 19 2019 2843

Introduction

In this tutorial, we will learn how to decode a base64 string, using the ESP32 and the Arduino core.

For a tutorial on how to encode content into base64 format, please check here. In the mentioned tutorial, we have used the base64.h library, which allowed us to encode a string by calling a simple static method of a class.

Nonetheless, that library doesn’t offer a method to decode a base64 string. So, in this tutorial, we will make use of a different library, the crypto/base64.h library. Although both libraries share the same “base64” word in the header definition, they are actually different.

The crypto/base64.h library is also available in the Arduino core, which means we don’t need to install any additional module.

Note that the crypto/base64.h also offers a method to to the base64 encoding of a string but, for this tutorial, we will use this online tool to encode the following plain text string:

Hello World Testing base64 encoding!

The result is the following base64 encoded string, which we are going to use in our Arduino code:

SGVsbG8gV29ybGQgVGVzdGluZyBiYXNlNjQgZW5jb2Rpbmch

The tests of this tutorial were performed using a DFRobot’s ESP32 module integrated in a ESP32 development board.

The code

As already mentioned, we are going to use the crypto/base64.h library, which means the first thing we should do is including it.

This include needs to be enclosed in an extern “C” block, in order for the code compilation process to work correctly. You can read more about this language linkage here.

extern "C" {
#include "crypto/base64.h"
}

Moving on to the setup function, the first thing we will do is opening a serial connection, to later output the decoded text.

Serial.begin(115200);

Next we will declare a string with the base64 encoded content, which was already shown in the introductory section.

char * toDecode = "SGVsbG8gV29ybGQgVGVzdGluZyBiYXNlNjQgZW5jb2Rpbmch";

We will also need a variable of type size_t, which will be used by the decoding function to return the size of the decoded content. We will check more about this below.

size_t outputLength;

To do the actual decoding, we need to call the base64_decode function of the crypto/base64.h library.

This function receives as first input the base64 string to decode, as a const unsigned char pointer. This means that we need to a cast since we declared our base64 string simply as a char pointer.

As second argument, the function receives the size of the message to decode, which we can obtain from our base64 string by using the strlen function.

As third argument, the base64_decode function receives a pointer to a variable of type size_t, which it uses to assign the length of the decoded string. So, we will pass as third input the address of the our previously declared outputLength variable.

As output, this function will return the decoded string, as an unsigned char pointer. We will store this result in a variable.

unsigned char * decoded = base64_decode((const unsigned char *)toDecode, strlen(toDecode), &outputLength);

To finalize, we will print the length of the decoded message and the actual decoded message.

In order to print the decoded message, we will make use of the printf function of the Serial object, which will allow us to use format specifiers.

So, we will use the %.*s format specifier, which basically allows us to print the result we obtained as a string, by specifying the size of the data and the buffer where it is stored (this buffer is the result of the base64_decode function).

Naturally, we could alternatively iterate through all the bytes of the result, since we have the length of the buffer. Nonetheless, using the mentioned format specifier leads to a much more compact syntax.

Serial.print("Length of decoded message: ");
Serial.println(outputLength);

Serial.printf("%.*s", outputLength, decoded);

Note that, as indicated in the source file of the library we are using, it’s responsibility of the base64_decode caller to free the memory allocated for the buffer that contains the decoded message.

So, after printing the final content, we should call the free function on the buffer pointer, in order to free the allocated memory.

free(decoded);

The final code can be seen below.

extern "C" {
#include "crypto/base64.h"
}

void setup() {
  Serial.begin(115200);

  char * toDecode = "SGVsbG8gV29ybGQgVGVzdGluZyBiYXNlNjQgZW5jb2Rpbmch";
  size_t outputLength;

  unsigned char * decoded = base64_decode((const unsigned char *)toDecode, strlen(toDecode), &outputLength);

  Serial.print("Length of decoded message: ");
  Serial.println(outputLength);

  Serial.printf("%.*s", outputLength, decoded);
  free(decoded);
}

void loop() {}

Testing the code

To test the code, simply compile it and upload it to your device, using the Arduino IDE with support for the ESP32 Arduino core.

When the procedure finishes, open the Arduino IDE serial monitor. You should have an output similar to figure 1, which shows the length of the decoded string and the actual decoded string, which matches the original sentence we have encoded in the online tool.

Ouput of decoding a base64 encoded string using the ESP32 and the Arduino core

Figure 1 – Output of the program, with the decoded content.