Files
2026-05-21 08:07:16 +08:00

85 lines
2.6 KiB
C

/*
* Base64 编码/解码实现
* 优化用于嵌入式系统
*/
#include "base64.h"
#include <string.h>
static const char base64_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* 函数作用:将二进制数据编码为 Base64 字符串。 */
uint32_t base64_encode(const uint8_t* input, uint32_t input_length, char* output)
{
uint32_t i, j;
uint32_t output_length = 0;
for (i = 0, j = 0; i < input_length;) {
uint32_t octet_a = i < input_length ? input[i++] : 0;
uint32_t octet_b = i < input_length ? input[i++] : 0;
uint32_t octet_c = i < input_length ? input[i++] : 0;
uint32_t triple = (octet_a << 16) + (octet_b << 8) + octet_c;
output[j++] = base64_chars[(triple >> 18) & 0x3F];
output[j++] = base64_chars[(triple >> 12) & 0x3F];
output[j++] = base64_chars[(triple >> 6) & 0x3F];
output[j++] = base64_chars[triple & 0x3F];
}
output_length = j;
// 处理padding
uint32_t mod = input_length % 3;
if (mod > 0) {
for (i = 0; i < 3 - mod; i++) {
output[output_length - 1 - i] = '=';
}
}
output[output_length] = '\0';
return output_length;
}
/* 函数作用:把 Base64 字符转换为 6 位数值。 */
static uint8_t base64_char_value(char c)
{
if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return 0;
}
/* 函数作用:将 Base64 字符串解码为二进制数据。 */
uint32_t base64_decode(const char* input, uint32_t input_length, uint8_t* output)
{
uint32_t i, j;
uint32_t output_length = 0;
if (input_length % 4 != 0) return 0;
for (i = 0, j = 0; i < input_length;) {
uint32_t sextet_a = input[i] == '=' ? 0 : base64_char_value(input[i]); i++;
uint32_t sextet_b = input[i] == '=' ? 0 : base64_char_value(input[i]); i++;
uint32_t sextet_c = input[i] == '=' ? 0 : base64_char_value(input[i]); i++;
uint32_t sextet_d = input[i] == '=' ? 0 : base64_char_value(input[i]); i++;
uint32_t triple = (sextet_a << 18) + (sextet_b << 12) + (sextet_c << 6) + sextet_d;
if (j < input_length) output[j++] = (triple >> 16) & 0xFF;
if (j < input_length) output[j++] = (triple >> 8) & 0xFF;
if (j < input_length) output[j++] = triple & 0xFF;
}
output_length = j;
// 移除padding
if (input[input_length - 1] == '=') output_length--;
if (input[input_length - 2] == '=') output_length--;
return output_length;
}