base64 的实现很简单,代码如下:
#include <stdio.h>
int base64_encode(const char *in_buf, int in_size, char *out_buf, int out_buf_size, int *out_size)
{
int i;
int j = 0;
int left = (in_size%3);
int len = in_size - left;
if(out_buf_size < len/3*4+(left+3)/4*4)
{
printf("input out_buf_size too short\n");
return -1;
}
char buf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned int value;
for(i = 0;i < len;i+=3){
value = 0;
value |= (in_buf[i+0]&0xff) << 16;
value |= (in_buf[i+1]&0xff) << 8;
value |= (in_buf[i+2]&0xff) << 0;
out_buf[j++] = buf[(value >> 18)&0x3f];
out_buf[j++] = buf[(value >> 12)&0x3f];
out_buf[j++] = buf[(value >> 6 )&0x3f];
out_buf[j++] = buf[(value >> 0 )&0x3f];
}
if(left == 2){
value = 0;
value |= (in_buf[len+0]&0xff) << 8;
value |= (in_buf[len+1]&0xff) << 0;
value = value << 2;
out_buf[j++] = buf[(value >> 12)&0x3f];
out_buf[j++] = buf[(value >> 6)&0x3f];
out_buf[j++] = buf[(value >> 0 )&0x3f];
out_buf[j++] = '=';
}else if(left == 1){
value = 0;
value |= (in_buf[len+0]&0xff);
value = value << 4;
out_buf[j++] = buf[(value >> 6)&0x3f];
out_buf[j++] = buf[(value >> 0)&0x3f];
out_buf[j++] = '=';
out_buf[j++] = '=';
}
*out_size = j;
return j;
}
int base64_decode(const char *in_buf, int in_size, char *out_buf, int out_buf_size, int *out_size)
{
unsigned int value;
int left ;
int len;
int i;
int j = 0;
*out_size = 0;
if(in_size < 3){
printf("input size too short");
return -1;
}
if(in_size % 4 != 0){
printf("input data length invaild\n");
return -1;
}
if(in_buf[in_size-1] == '='){
len = in_size - 4;
left = 4;
}else{
len = in_size;
}
if(out_buf_size < len/4*3){
printf("out buf size too short\n");
return -1;
}
char table[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
-1, 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,-1,-1,-1,-1,-1,
-1,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,-1,-1,-1,-1,-1
};
for(i = 0;i < len;i+=4){
value = 0;
int k;
for(k = 0;k < 4; k++){
if(in_buf[i+k]&0x80){
printf("input invaild base64 format\n");
return -1;
}
if(table[in_buf[i+k]] < 0){
printf("input invaild base64 format\n");
return -1;
}
}
value |= table[(in_buf[i+0]&0x7f)] << 18;
value |= table[(in_buf[i+1]&0x7f)] << 12;
value |= table[(in_buf[i+2]&0x7f)] << 6;
value |= table[(in_buf[i+3]&0x7f)] << 0;
out_buf[j++] = (value >> 16)&0xff;
out_buf[j++] = (value >> 8 )&0xff;
out_buf[j++] = (value >> 0 )&0xff;
}
if(left > 0){
int k;
for(k = 0;k < 4; k++){
if(in_buf[i+k]&0x80){
printf("input invaild base64 format\n");
return -1;
}
if(in_buf[i+k]!= '=' && table[in_buf[i+k]] < 0){
printf("input invaild base64 format\n");
return -1;
}
}
if(in_buf[in_size-2] == '='){
value = 0;
value |= table[(in_buf[in_size-4]&0x7f)] << 6;
value |= table[(in_buf[in_size-3]&0x7f)] << 0;
value = value >> 4;
out_buf[j++] = value &0xff;
}else{
value = 0;
value |= table[(in_buf[in_size-4]&0x7f)] << 12;
value |= table[(in_buf[in_size-3]&0x7f)] << 6;
value |= table[(in_buf[in_size-2]&0x7f)] << 0;
value = value >> 2;
out_buf[j++] = (value >> 8) & 0xff;
out_buf[j++] = (value >> 0) & 0xff;
}
}
*out_size = j;
return j;
}