C 语言关于base64 解码的bug?

作者站长头像
站长
· 阅读数 17

老师们好, 下面这段代码,解码这样一段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;
}
回复
1个回答
avatar
test
2024-06-30
#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;
}
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容