quejing
发布于 2024-02-29 / 710 阅读
0

C语言实现base64编码与解码

记录一下项目中用到的base64代码。base64的基础知识就不再记录了。

初步测试能够正常编码和解码。

代码中如果存在问题请帮忙指出,万分感谢!!

base64编码代码:

#include <stdio.h>

static const unsigned char *base64_char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int base64_encode(const unsigned char *bytes_to_encode, unsigned int in_len, unsigned char *encode_result, unsigned int *out_len) {
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];

    *out_len = 0;
    while (in_len--) {
        char_array_3[i++] = *(bytes_to_encode++);
        if (i == 3) {
            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
            char_array_4[3] = char_array_3[2] & 0x3f;

            for (i = 0; (i < 4); i++) {
                encode_result[*out_len] = base64_char[char_array_4[i]];
                *out_len = *out_len + 1;
            }
            i = 0;
        }
    }

    if (i) {
        for (j = i; j < 3; j++)
            char_array_3[j] = '\0';

        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);

        for (j = 0; (j < i + 1); j++) {
                encode_result[*out_len] = base64_char[char_array_4[j]];
                *out_len = *out_len + 1;
            }

        while ((i++ < 3)) {
            encode_result[*out_len] = '=';
            *out_len = *out_len + 1;
        }
    }
    return 0;
}

base64解码代码:

static unsigned char change_char_to_value(char value)
{
    if (value >= '0' && value <= '9') {
        return value - '0' + 52;
    } else if (value >= 'a' && value <= 'z') {
        return value - 'a' + 26;
    } else  if (value >= 'A' && value <= 'Z') {
        return value - 'A';
    } else  if (value == '+') {
        return 62;
    } else  if (value == '/') {
        return 63;
    } else  if (value == '=') {
        return 64;
    }
    return 65;
}

int base64_decode(const unsigned char *bytes_to_decode, unsigned int in_len, unsigned char *decode_result, unsigned int *out_len)
{
    int i = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];
    int index = 0;
    int space_flag_count = 0;

    if (in_len % 4) { // 字符串长度有问题,无法继续处理!
        printf("decode has error, return!\n");
        *out_len = 0;
        return -1;
    }

    *out_len = 0;
    while (index < in_len) {
        unsigned temp_value = change_char_to_value(bytes_to_decode[index++]);
        if (temp_value > 64) {  // 存在非base64编码的字符,无法继续处理!
            printf("decode has error char, return!\n");
            *out_len = 0;
            return -1;
        }

        char_array_4[i++] = temp_value;
        if (temp_value == 64) { // 出现 = ,判断位置是否正确,如果不是在最后(=或者==),说明字符串存在异常,无法继续处理!
            int position = in_len - index;
            if (position > 1 ) {
                printf("decode has error position =, return!\n");
                *out_len = 0;
                return -1;
            } else if (position == 1) {
                if (change_char_to_value(bytes_to_decode[index]) != 64) {
                    printf("decode has error position = , last, return!\n");
                    *out_len = 0;
                    return -1;
                }
            }
            space_flag_count++;
        }

        if (i == 4) {
            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

            for (i = 0; (i < 3); i++) {
                decode_result[*out_len] = char_array_3[i];
                *out_len = *out_len + 1;
            }
            i = 0;
        }
    }

    if (space_flag_count == 1) {
        *out_len = *out_len - 1;
        decode_result[*out_len] = 0;
    } else if (space_flag_count == 2) {
        *out_len = *out_len - 1;
        decode_result[*out_len] = 0;
        *out_len = *out_len - 1;
        decode_result[*out_len] = 0;
    }

    return 0;
}