短字符串 Base64 解碼正常,長字符串(數百字符)解碼後數據長度僅 124 字節,明顯截斷。
bindata 空間不足,導致寫入越界或截斷break 直接跳出,未處理剩餘數據#include
#include
static const char b64_table[256] = {
['A']=0, ['B']=1, ['C']=2, ['D']=3, ['E']=4, ['F']=5, ['G']=6, ['H']=7,
['I']=8, ['J']=9, ['K']=10, ['L']=11, ['M']=12, ['N']=13, ['O']=14, ['P']=15,
['Q']=16, ['R']=17, ['S']=18, ['T']=19, ['U']=20, ['V']=21, ['W']=22, ['X']=23,
['Y']=24, ['Z']=25, ['a']=26, ['b']=27, ['c']=28, ['d']=29, ['e']=30, ['f']=31,
['g']=32, ['h']=33, ['i']=34, ['j']=35, ['k']=36, ['l']=37, ['m']=38, ['n']=39,
['o']=40, ['p']=41, ['q']=42, ['r']=43, ['s']=44, ['t']=45, ['u']=46, ['v']=47,
['w']=48, ['x']=49, ['y']=50, ['z']=51, ['0']=52, ['1']=53, ['2']=54, ['3']=55,
['4']=56, ['5']=57, ['6']=58, ['7']=59, ['8']=60, ['9']=61, ['+']=62, ['/']=63,
['=']=0 // 填充字符映射為 0
};
int base64_decode(const char *input, unsigned char **output) {
if (!input) return -1;
size_t len = strlen(input);
if (len % 4 != 0) return -2; // 長度必須是 4 的倍數
size_t out_len = len / 4 * 3;
// 處理填充
if (input[len-1] == '=') out_len--;
if (input[len-2] == '=') out_len--;
unsigned char *out = malloc(out_len + 1);
if (!out) return -3;
for (size_t i = 0, j = 0; i < len; i += 4, j += 3) {
uint32_t sextet[4];
for (int k = 0; k < 4; k++) {
unsigned char c = input[i+k];
if (c > 127 || b64_table[c] == 0 && c != '=') { free(out); return -4; }
sextet[k] = b64_table[c];
}
out[j] = (sextet[0] << 2) | (sextet[1] >> 4);
if (i+2 < len && input[i+2] != '=') out[j+1] = (sextet[1] << 4) | (sextet[2] >> 2);
if (i+3 < len && input[i+3] != '=') out[j+2] = (sextet[2] << 6) | sextet[3];
}
out[out_len] = '\0';
*output = out;
return out_len;
}
freeunsigned char *decoded;
int len = base64_decode(long_base64_string, &decoded);
if (len > 0) {
// 使用 decoded[0..len-1]
free(decoded);
}
Base64 解碼核心:4字符→3字節,填充減少輸出生成。生產環境建議用 OpenSSL
EVP_DecodeBlock或成熟庫(libb64, Apache Commons Codec)。