82 lines
2.4 KiB
C
82 lines
2.4 KiB
C
/*
|
|
* Base64 编码/解码实现
|
|
* 优化用于嵌入式系统
|
|
*/
|
|
|
|
#include "base64.h"
|
|
#include <string.h>
|
|
|
|
static const char base64_chars[] =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|