ESP-IDFを使ってみる

BASE64 Encode/Decode


ESP-IDFにはこちらのMbed TLSライブラリが含まれています。
Mbed TLSライブラリの説明はこちらに有りま すが、SSL/TSLを提供するライブラリです。
ESP-IDFにはコンポーネントの1つとして組み込まれ、ソースはcomponents/mbedtlsに置かれます。
サンプルコードがこ ちらに公開されています。
インクルードするファイルを変えるだけでesp-idfでも動きます。



Mbed TLSライブラリの中にBASE64 Encode/Decodeの関数が有りました。
バイナリーデータを簡単にBASE64文字列に変換することができます。
簡単なサンプルで確認してみました。
なお、BASE64変換後のサイズ計算はこ ちらから借用しました。ありがとうございます。
encodeする場合、encodeされた文字列はNULL終端になるので、+1文字分の領域が必要です。
/* The example of BASE64 Encode/Decode
 *
 * This sample code is in the public domain.
 */

#include <stdio.h>
#include <mbedtls/base64.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

static const char *TAG = "BASE64";

// Calculate the size after conversion to base64
// https://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
int32_t calcBase64EncodedSize(int input_length)
{
    int32_t output_length = 4 * ((input_length + 2) / 3);
    return output_length;
}

// Calculate the size after conversion from base64
int32_t calcBase64DecodedSize(int input_length)
{
    int32_t output_length = input_length / 4 * 3;;
    return output_length;
}

void app_main()
{
    unsigned char src_buffer[32];
    for(int i=0;i<sizeof(src_buffer);i++) src_buffer[i] = i;
    ESP_LOG_BUFFER_HEXDUMP(TAG, src_buffer, sizeof(src_buffer), ESP_LOG_INFO);

    // Calculate the size after conversion to base64
    int32_t EncodedSize = calcBase64EncodedSize(sizeof(src_buffer));
    ESP_LOGI(TAG, "EncodedSize=%d", EncodedSize);

    // Allocate encode memory
    unsigned char* encode_buffer = NULL;
    encode_buffer = malloc(EncodedSize+1);
    if (encode_buffer == NULL) {
        ESP_LOGE(TAG, "malloc fail. encode_buffer %d", EncodedSize);
        while(1) { vTaskDelay(1); }
    }

    // Encode to Base64
    size_t encode_len;
    int ret = mbedtls_base64_encode(encode_buffer, EncodedSize+1, &encode_len, src_buffer, sizeof(src_buffer));
    if (ret != 0) {
        ESP_LOGE(TAG, "Error in mbedtls encode! ret = -0x%x", -ret);
        while(1) { vTaskDelay(1); }
    }
    ESP_LOGI(TAG, "encode_len=%d", encode_len);
    ESP_LOG_BUFFER_HEXDUMP(TAG, encode_buffer, encode_len, ESP_LOG_INFO);

    // Calculate the size after conversion from base64
    int32_t DecodedSize = calcBase64DecodedSize(EncodedSize);
    ESP_LOGI(TAG, "DecodedSize=%d", DecodedSize);

    // Allocate decode memory
    unsigned char* decode_buffer = NULL;
    decode_buffer = malloc(DecodedSize+1);
    if (decode_buffer == NULL) {
        ESP_LOGE(TAG, "malloc fail. decode_buffer %d", EncodedSize);
        while(1) { vTaskDelay(1); }
    }

    // Decode from Base64
    size_t decode_len;
    ret = mbedtls_base64_decode( decode_buffer, DecodedSize+1, &decode_len, encode_buffer, encode_len);
    if (ret != 0) {
        ESP_LOGE(TAG, "Error in mbedtls decode! ret = -0x%x", -ret);
        while(1) { vTaskDelay(1); }
    }
    ESP_LOGI(TAG, "decode_len=%d", decode_len);
    ESP_LOG_BUFFER_HEXDUMP(TAG, decode_buffer, decode_len, ESP_LOG_INFO);

    if (encode_buffer != NULL) free(encode_buffer);
    if (decode_buffer != NULL) free(decode_buffer);
}

実行すると以下の表示となります。
0から32のバイナリーデータをBASE64の文字列に変換し、BASE64の文字列を再びバイナリーデータに復元します。
32バイトのバイナリーデータをBASE64に変換すると44バイトになります。
44バイトのBASE64データを復元すると32バイトになります。
I (320) BASE64: 0x3ffb5800   00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  |................|
I (330) BASE64: 0x3ffb5810   10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f  |................|
I (340) BASE64: EncodedSize=44
I (340) BASE64: encode_len=44
I (350) BASE64: 0x3ffaffac   41 41 45 43 41 77 51 46  42 67 63 49 43 51 6f 4c  |AAECAwQFBgcICQoL|
I (360) BASE64: 0x3ffaffbc   44 41 30 4f 44 78 41 52  45 68 4d 55 46 52 59 58  |DA0ODxAREhMUFRYX|
I (370) BASE64: 0x3ffaffcc   47 42 6b 61 47 78 77 64  48 68 38 3d              |GBkaGxwdHh8=|
I (370) BASE64: DecodedSize=33
I (380) BASE64: decode_len=32
I (380) BASE64: 0x3ffb6918   00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  |................|
I (390) BASE64: 0x3ffb6928   10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f  |................|

BASE64のEncodeはこ ちらのサンプルの中で、添付ファイル(esp_logo.png)のEncodeに使われています。
PNGイメージのエンコーダーを探していたら偶然、このライブラリを見つけました。

続く...