C語言實現Base64算法
/ Base64是一種基于64個可打印字符來表示二進制數據的表示方法。三個字節有24個比特,對應于4個Base64單元,即3個字節需要用4個可打印字符來表示。 當最后剩余一個八位字節(一個byte)時,最后一個6位的base64字節塊有四位是0值,最后附加上兩個等號; 如果最后剩余兩個八位字節(2個byte)時,最后一個6位的base字節塊有兩位是0值,最后附加一個等號。/include <stdio.h>
include "string.h"
include "stdlib.h"
const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; static char find_pos(char ch); char base64_encode(const char data, int data_len,int len); char base64_decode(const char data, int data_len,int len);
/* 找到ch在base中的位置 / static char find_pos(char ch)
{
//the last position (the only) in base[] char ptr = (char*)strrchr(base, ch); return (ptr - base);
}/* BASE64編碼 / char base64_encode(const char data, int data_len,int len)
{
int prepare = 0;
int ret_len;
len=0; int temp = 0;
char ret = NULL;
char f = NULL;
int tmp = 0;
char changed[4];
int i = 0;
ret_len = data_len / 3;
temp = data_len % 3;
if (temp > 0)
{
ret_len += 1;
}
//最后一位以''結束 ret_len = ret_len4 + 1;
ret = (char *)malloc(ret_len);if ( ret == NULL) { printf("No enough memory.n"); exit(0); } memset(ret, 0, ret_len); f = ret; //tmp記錄data中移動位置 while (tmp < data_len) { temp = 0; prepare = 0; memset(changed, 0, 4); while (temp < 3) { if (tmp >= data_len) { break; } //將data前8*3位移入prepare的低24位 prepare = ((prepare << 8) | (data[tmp] & 0xFF)); tmp++; temp++; } //將有效數據移到以prepare的第24位起始位置 prepare = (prepare<<((3-temp)*8)); for (i = 0; i < 4 ;i++ ) { //最后一位或兩位 if (temp < i) { changed[i] = 0x40; } else { //24位數據 changed[i] = (prepare>>((3-i)*6)) & 0x3F; } *f = base[changed[i]]; f++; (*len)++; } } *f = ''; return ret;
}
/* BASE64解碼 / char base64_decode(const char data, int data_len,int len)
{
int ret_len = (data_len / 4) 3+1;
int equal_count = 0;
char ret = NULL;
char f = NULL; len=0; int tmp = 0;
int temp = 0;
char need[3];
int prepare = 0;
int i = 0;
if ((data + data_len - 1) == '=')
{
equal_count += 1;
}
if ((data + data_len - 2) == '=')
{
equal_count += 1;
}ret = (char *)malloc(ret_len); if (ret == NULL) { printf("No enough memory.n"); exit(0); } memset(ret, 0, ret_len); f = ret; while (tmp < (data_len - equal_count)) { temp = 0; prepare = 0; memset(need, 0, 4); while (temp < 4) { if (tmp >= (data_len - equal_count)) { break; } prepare = (prepare << 6) | (find_pos(data[tmp])); temp++; tmp++; } prepare = prepare << ((4-temp) * 6); for (i=0; i<3 ;i++ ) { if (i == temp) { break; } *f = (char)((prepare>>((2-i)*8)) & 0xFF); f++; (*len)++; } } *f = ''; if(data[data_len-1]=='=') { (*len)--; } /* while(*(--f)=='') { (*len)--; } */ return ret;
} int main(){ char former = "hello"; int len1,len2; printf("%sn",former); char after = base64_encode(former, 5,&len1); printf("%d %sn",len1,after); former = base64_decode(after, len1,&len2); printf("%d %sn",len2,former); }</pre>