Base64 は電子メールに画像を添付する際に用いられる変換形式です。
RFC 4648で標準化されている。
RFC 4648 - The Base16, Base32, and Base64 Data Encodings
仕様はシンプルなので仕様とおりに作ればよいが。 6ビット毎に変換するので、C言語で実装するのは、面倒です。
ここは先人の知恵に頼ることにする。
下記にあるコードをそのまま借用する。
qiita: CでBASE64のエンコード/デコードを行う関数
char *base64Encode(const char *data, const size_t size, const BASE64_TYPE type) { BASE64_SPEC spec; size_t length; char *base64; char *cursor; int lineLength; int i; int j; if (data == NULL) { return NULL; } spec = BASE64_SPECS[0]; for (i = 0; i < (int)BASE64_SPECS_LENGTH; i++) { if (BASE64_SPECS[i].type == type) { spec = BASE64_SPECS[i]; break; } } length = size * 4 / 3 + 3 + 1; if (spec.maxLineLength > 0) { length += size / spec.maxLineLength * spec.lineSepLength; } base64 = malloc(length); if (base64 == NULL) { return NULL; } cursor = base64; lineLength = 0; for (i = 0, j = size; j > 0; i += 3, j -= 3) { if (spec.maxLineLength > 0) { if (lineLength >= spec.maxLineLength) { char *sep; for (sep = spec.lineSep; *sep != 0; sep++) { *(cursor++) = *sep; } lineLength = 0; } lineLength += 4; } if (j == 1) { *(cursor++) = spec.table[(data[i + 0] >> 2 & 0x3f)]; *(cursor++) = spec.table[(data[i + 0] << 4 & 0x30)]; *(cursor++) = spec.pad; *(cursor++) = spec.pad; } else if (j == 2) { *(cursor++) = spec.table[(data[i + 0] >> 2 & 0x3f)]; *(cursor++) = spec.table[(data[i + 0] << 4 & 0x30) | (data[i + 1] >> 4 & 0x0f)]; *(cursor++) = spec.table[(data[i + 1] << 2 & 0x3c)]; *(cursor++) = spec.pad; } else { *(cursor++) = spec.table[(data[i + 0] >> 2 & 0x3f)]; *(cursor++) = spec.table[(data[i + 0] << 4 & 0x30) | (data[i + 1] >> 4 & 0x0f)]; *(cursor++) = spec.table[(data[i + 1] << 2 & 0x3c) | (data[i + 2] >> 6 & 0x03)]; *(cursor++) = spec.table[(data[i + 2] << 0 & 0x3f)]; } } *cursor = 0; return base64; }
やはり難しいので、コード解説はしない。
サンプルコードを Guthub に公開した。
https://github.com/ohwada/MAC_cpp_Samples/tree/master/binary/base64