base64编码,C语言实现

本文介绍了Base64编码方案,包括其编码表和实现方法,以及在HTTP头和JSON中的应用。还提供了C语言代码示例,包括encode_base64和decode_base64函数,以及检查字符是否在Base64范围内的辅助函数。
摘要由CSDN通过智能技术生成


前言

base64是一种编码方案,将二进制字节流编码成可显示字符,其中可显示字符有64种,如下表所示。

在http头,JSON等格式中,要求必须为可显示字符,如果想将二进制字节流加入http头或JSON中可将其用base64转换成字符后加入到协议中。


一、编码表

对应base64字符对应base64字符对应base64字符
0x0A26a520
0x1B27b531
Cc2
Dd3
Ee4
Ff5
Gg6
Hh7
Ii8
Jj9
Kk+
Ll63/
Mm
Nn
Oo
Pp
Qq
Rr
Ss
Tt
Uu
Vv
Ww
Xx
Yy
25Zz

在这里插入图片描述

在这里插入图片描述

不足的用’='代替

二、实现

欢迎指出程序中的bug

#include <stdio.h>
#include <stdbool.h>

bool encode_base64(const char* src, int s_len, char* dest, int* d_len)
{
    static unsigned char table[] = {
        65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
        97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,
        '0', 49, 50, 51, 52, 53, 54, 55, 56, 57, '+', '/',
    };
    if ( *d_len < ((s_len + 2) / 3 * 4) + 1 ) return false;
    int round_len = s_len / 3 * 3;
    *d_len = 0;
    for (int i = 0; i+2 < round_len; i += 3)
    {
        dest[(*d_len)++] = table[src[i] >> 2];
        dest[(*d_len)++] = table[ ((src[i]&0x03) << 4) | ((src[i+1]&0xF0) >> 4) ];
        dest[(*d_len)++] = table[ ((src[i+1]&0x0F) << 2) | ((src[i+2]&0xC0) >> 6) ];
        dest[(*d_len)++] = table[ src[i+2]&0x3F ];
    }
    if (s_len - round_len == 2) {
        dest[(*d_len)++] = table[src[round_len] >> 2];
        dest[(*d_len)++] = table[ ((src[round_len]&0x03) << 4) | ((src[round_len+1]&0xF0) >> 4) ];
        dest[(*d_len)++] = table[ ((src[round_len+1]&0x0F) << 2) ];
        dest[(*d_len)++] = '=';
    } else if (s_len - round_len == 1) {
        dest[(*d_len)++] = table[src[round_len] >> 2];
        dest[(*d_len)++] = table[ ((src[round_len]&0x03) << 4) ];
        dest[(*d_len)++] = '=';
        dest[(*d_len)++] = '=';
    }
    dest[*d_len] = '\0';
    return true;
}
static inline bool not_in_base64(unsigned char ch)
{
    if (ch == '=' || ch == 43 || (ch >= 47 && ch <= 57) || (ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122)) return false;
    return true;
}
bool decode_base64(const char* src, int s_len, char* dest, int* d_len)
{
    static unsigned char table[] = {
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        62/* 43 '+' */, 0,0,0, 63/* 47 '/' */, 52/* 48 '0' */, 53, 54, 55, 56, 57, 58, 59, 60, 61,
        0,0,0,0,0,0,0/* 64 */,
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25/* 90 */,
        0, 0, 0, 0, 0, 0/* 96 */,
        26, 27, 28, 29, 30, 31, 32, 33,34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51/* 122 */,
    };
    if (s_len % 4 != 0) return false;
    *d_len = 0;
    for (int i = 0; i + 4 <= s_len; i += 4)
    {
        if (not_in_base64(src[i  ])) return false;
        if (not_in_base64(src[i+1])) return false;
        if (not_in_base64(src[i+2])) return false;
        if (not_in_base64(src[i+3])) return false;
        dest[(*d_len)++] = (table[src[i]] << 2) | (table[src[i+1]] >> 4);
        dest[(*d_len)++] = (table[src[i+1]] << 4) | (table[src[i+2]] >> 2);
        dest[(*d_len)++] = (table[src[i+2]] << 6) | (table[src[i+3]]);
    }
    if ('=' == src[s_len-1]) --(*d_len);
    if ('=' == src[s_len-2]) --(*d_len);
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值