C 语言关于base64 解码的bug?

老师们好, 下面这段代码,解码这样一段base64编码的字符串(KioqKipAI++/pSXigKbigKYmKiPvv6Ul4oCm4oCmJio=), 后面多了个“)”

解码正确的内容是:*****@#¥%……&*#¥%……&*
解码错误的内容是:*****@#¥%……&*#¥%……&)

找不到原因了, 请老师们帮忙看看。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>


int base64_decode_char(char c) {
    if (c >= 'A' && c <= 'Z') {
        return c - 'A';
    } else if (c >= 'a' && c <= 'z') {
        return c - 'a' + 26;
    } else if (c >= '0' && c <= '9') {
        return c - '0' + 52;
    } else if (c == '+') {
        return 62;
    } else if (c == '/') {
        return 63;
    } else {
        return -1;
    }
}

unsigned char *base64_decode(const char *input, size_t input_len, size_t *output_len) {
    if (input_len % 4 != 0) {
        fprintf(stderr, "输入字符串长度错误!\n");
        return NULL;
    }

    size_t output_size = input_len / 4 * 3;
    if (input[input_len - 1] == '=') {
        output_size--;
    }
    if (input[input_len - 2] == '=') {
        output_size--;
    }

    unsigned char *output = (unsigned char *)malloc(output_size);
    if (output == NULL) {
        fprintf(stderr, "内存分配失败!\n");
        return NULL;
    }

    size_t i, j;
    for (i = 0, j = 0; i < input_len;) {
        uint32_t sextet_a = base64_decode_char(input[i++]);
        uint32_t sextet_b = base64_decode_char(input[i++]);
        uint32_t sextet_c = base64_decode_char(input[i++]);
        uint32_t sextet_d = base64_decode_char(input[i++]);

        uint32_t triple = (sextet_a << 18) + (sextet_b << 12) + (sextet_c << 6) + sextet_d;

        if (j < output_size) {
            output[j++] = (triple >> 16) & 0xFF;
        }
        if (j < output_size) {
            output[j++] = (triple >> 8) & 0xFF;
        }
        if (j < output_size) {
            output[j++] = triple & 0xFF;
        }
    }

    *output_len = output_size;

    return output;
}

int main() {
    const char *input = "KioqKipAI++/pSXigKbigKYmKiPvv6Ul4oCm4oCmJio=";
    size_t input_len = strlen(input);

    size_t output_len;
    unsigned char *decoded = base64_decode(input, input_len, &output_len);
    if (decoded != NULL) {
        printf("Base64解码结果:%s\n", decoded);
        free(decoded);
    }

    return 0;
}
阅读 2k
2 个回答
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>


int base64_decode_char(char c) {
    if (c >= 'A' && c <= 'Z') {
        return c - 'A';
    } else if (c >= 'a' && c <= 'z') {
        return c - 'a' + 26;
    } else if (c >= '0' && c <= '9') {
        return c - '0' + 52;
    } else if (c == '+') {
        return 62;
    } else if (c == '/') {
        return 63;
    } else {
        return -1;
    }
}

unsigned char *base64_decode(const char *input, size_t input_len, size_t *output_len) {
    if (input_len % 4 != 0) {
        fprintf(stderr, "输入字符串长度错误!\n");
        return NULL;
    }

    size_t output_size = input_len / 4 * 3;
    if (input[input_len - 1] == '=') {
        output_size--;
    }
    if (input[input_len - 2] == '=') {
        output_size--;
    }

    unsigned char *output = (unsigned char *)malloc(output_size + 1);  // extra byte for null character
    if (output == NULL) {
        fprintf(stderr, "内存分配失败!\n");
        return NULL;
    }

    size_t i, j;
    for (i = 0, j = 0; i < input_len;) {
        uint32_t sextet_a = input[i] == '=' ? 0 & i++ : base64_decode_char(input[i++]);
        uint32_t sextet_b = input[i] == '=' ? 0 & i++ : base64_decode_char(input[i++]);
        uint32_t sextet_c = input[i] == '=' ? 0 & i++ : base64_decode_char(input[i++]);
        uint32_t sextet_d = input[i] == '=' ? 0 & i++ : base64_decode_char(input[i++]);

        uint32_t triple = (sextet_a << 18) + (sextet_b << 12) + (sextet_c << 6) + sextet_d;

        if (j < output_size) output[j++] = (triple >> 16) & 0xFF;
        if (j < output_size) output[j++] = (triple >> 8) & 0xFF;
        if (j < output_size) output[j++] = triple & 0xFF;
    }

    output[output_size] = '\0';  // null character at the end
    *output_len = output_size;

    return output;
}

int main() {
    const char *input = "KioqKipAI++/pSXigKbigKYmKiPvv6Ul4oCm4oCmJio=";
    size_t input_len = strlen(input);

    size_t output_len;
    unsigned char *decoded = base64_decode(input, input_len, &output_len);
    if (decoded != NULL) {
        printf("Base64解码结果:%s\n", decoded);
        free(decoded);
    }

    return 0;
}

%s 输出的就以 0 结尾的字符串。在 decode 的过程中生成的串并没有结尾的 0 ,所以会导致输出错误。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进