/*
说明:
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,
在发送电子邮件时,服务器认证的用户名和密码需要用Base64编码,附件也需要用Base64编码。
下面简单介绍Base64算法的原理:
1:Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),
2:然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。
3: 转换后,我们用一个码表来得到我们想要的字符串(也就是最终的Base64编码),
这个表是这样的: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=这65个可显示字符
4:原文的字节最后不够3个的地方用0来补足,转换时Base64编码用=号来代替。
这就是为什么有些Base64编码会以一个或两个等号结束的原因,但等号最多只有两个。
举一个例子,abc经过Base64编码以后的结果是YWJj. 发邮件的时候所写的信息自动在后台转换然后传输..
原理:###############################################################################################
Base64 使用US-ASCII子集的64个字符,即大小写的26个英文字母,0-9,+,/。
编码总是基于3个字符,每个字符用8位二进制表示,因此一共24位,再分为4四组,每组6位,表示一个Base64的值。如下:
"A", "B", "C", "D", "E", "F", "G", "H", "I","J", "K", "L", "M", "N", "O", "P",
"Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f",
"g", "h", "i","j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"
Base64值为0就是A,为27的就是b。这样,每3个字符产生4位的Base64字符。
如果被加密的字符串每3个一组,还剩1或2个字符,使用特殊字符"="补齐Base64的4字。
如,编码只有2个字符“me”,m的ascii是109,e的是101,用二进制表示分别是01101101、01100101,连接起来就是0110110101100101,
再按6位分为一组:011011、010110、010100(不足6位补0),
分别ascii分别是27、22、20,即Base64值为bWU,Base64不足4字,用=补齐,因此bWU=就me的Base64值。
#####################################################################################################
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char gBase64Table[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
char *Base64Encode(char *epSrc, char * opDes);
char * Byte3to4(char *epSrc, char *opDes);
char * ASCIIToBit(char ecSrc);
char *Base64Decode(char * epSrc ,char *c);
/*
功能:BASE64编码
参数:
1:epSrc----------------------编码字符串
2:opDes---------------------BASE64字符串
返回值:
成功:BASE64字符串
失败:NULL
*/
char *Base64Encode(char *epSrc, char * opDes) {
int iSrcLength = 0;
int iDesLength = 0;
int reste = 0;
int padding = 0;
char * p;
int i = 0;
int j = 0;
char src[3 * 8 + 1];
char des[4 * 8 + 1];
char temp[8+1];
int index =-1;
if (epSrc == NULL || opDes == NULL) {
fprintf(stderr, "%d, epSrc =[%p] opDes = [%p] \n", __LINE__, epSrc,
opDes);
return NULL;
}
reste = strlen(epSrc)%3;
if(reste != 0){
padding = 3-reste;
}else{
padding = 0;
}
//格式成二进制
for( i = 0; i*3<STRLEN(EPSRC);I++)
{
memset(src,0,sizeof(src) );
memset (des,0,sizeof(des) );
memcpy(src ,epSrc+i*3,3);
Byte3to4(src ,des);
if(des == NULL)
{
fprintf(stderr, "%d Byte3to4(src ,des); is error \n",__LINE__);
return NULL;
}
for( j = 0; j <STRLEN(SRC)+1 ;J++){
memset(temp,0,sizeof(temp));
memcpy(temp ,des + j*8, 8);
index =BitToInt(temp);
if(index ==-1){
fprintf(stderr,"%d index error\n",__LINE__);
return NULL;
}
opDes[i*4 +j] = gBase64Table[index];
}
}//end for
iDesLength = strlen(opDes);
while(padding--){
opDes[iDesLength++]= '=';
}
fprintf(stderr, "%d length = [%d],BIT = [%s]\n", __LINE__,strlen(opDes), opDes);
return opDes;
}
/*功能: 由3个字节变成4个字节
参数:
1)epSrc
2)opDes
*/
char * Byte3to4(char *epSrc, char *opDes) {
char src[3 * 8 + 1];
char des[4 * 8 + 1];
char temp[8 + 1];
int i = 0;
int padding = 0;
int reste = 0;
int length=0;
memset(src, 0, sizeof(src));
memset(des, 0, sizeof(des));
if (epSrc == NULL || opDes == NULL) {
fprintf(stderr, "%d, epSrc =[%p] opDes = [%p] \n", __LINE__, epSrc,
opDes);
return NULL;
}
//得到ASCII二进制形式
for (i = 0; i < strlen(epSrc); i++) {
memset(temp, 0, sizeof(temp));
strcpy(temp, ASCIIToBit(epSrc[i]));
if (temp == NULL) {
fprintf(stderr, "%d ASCIIToBit error temp = [%s]\n", __LINE__, temp);
} else {
memcpy(des + i * 8, temp, 8);
}
}
length = strlen(des);
reste = length%6 ;
if(reste !=0){
padding = 6 -reste;
}else{
padding = 0;
}
while(padding--){
des[length++] ='0';
}
fprintf(stderr,"%d length = [%d] des =[%s]\n",__LINE__,strlen(des),des);
//3B---->4B
for( i = 0;i< strlen(epSrc)+1;i++){
memset(opDes+i*8,'0',2);
memcpy(opDes +i*8+2,des+i*6,6);
}
fprintf(stderr,"%d length = [%d] opDes =[%s]\n",__LINE__,strlen(opDes),opDes);
return opDes;
}
/*功能:将一个ASCII变成二进制形式展开
参数:
1)ecSrc
*/
char * ASCIIToBit(char ecSrc) {
int i = 0;
char result[8 + 1];
memset(result, 0, sizeof(result));
result[0] = (ecSrc & 0x80) ==0x00 ?'0': (ecSrc & 0x80) -0x7F+ 48;
result[1] = (ecSrc & 0x40) ==0x00 ?'0': (ecSrc & 0x40) -0x3F+ 48;
result[2] = (ecSrc & 0x20) ==0x00 ?'0': (ecSrc & 0x20) -0x1F+ 48;
result[3] = (ecSrc & 0x10) ==0x00 ?'0': (ecSrc & 0x10) -0x0F+ 48;
result[4] = (ecSrc & 0x08) ==0x00 ?'0': (ecSrc & 0x08) -0x07+ 48;
result[5] = (ecSrc & 0x04) ==0x00 ?'0': (ecSrc & 0x04) -0x03+ 48;
result[6] = (ecSrc & 0x02) ==0x00 ?'0': (ecSrc & 0x02) -0x01+ 48;
result[7] = (ecSrc & 0x01) ==0x00 ?'0': (ecSrc & 0x01) -0x00+ 48;
fprintf(stderr, "%d,ecSrc = [%c] result = [%s]\n ",__LINE__,ecSrc, result);
return result;
}
/*
*功能:将二进制字符串转换成十进制数
*参数:
* 1)epSrc
* 返回值:
* 成功:十进制数值
* 失败:-1
*/
int BitToInt(char *epSrc)
{
int i=0;
int iLength=0;
int sum=0;
char c;
int j = 0;
if(epSrc == NULL){
fprintf(stderr,"%d epSrc = [%s] error \n",__LINE__,epSrc);
return -1;
}
iLength = strlen(epSrc);
for(i = iLength-1, j=0; i>=0;i--,j++){
c = epSrc[i];
if(c =='1'){
sum +=0x01<<J;
}
}
fprintf(stderr, "%d ,sum = [%d] epSrc =[%s]\n",__LINE__,sum,epSrc);
return sum;
}
/*
* 功能:BASE64解码
* 参数:
* 1)epSrc-------------------
* 2)epSrc-------------------
*
*/
char *Base64Decode(char * epSrc ,char *c)
{
return NULL;
}
int main(int argc ,char *args[]) {
//char *src = "AB";
//char des[4 * 8+1];
char *des=NULL;
if(argc !=2){
fprintf(stderr,"USEAGE: ./a.out abc\n");
exit (-1);
}
des = (char *)malloc(sizeof(char ) * strlen(args[1]));
if(des == NULL){
fprintf(stderr,"%d ,des malloc error \n",__LINE__);
exit (-1);
}
Base64Encode(args[1], des);
return 0;
}
暂没有写其解码过,有兴趣的请一起交流:QQ153612021
[
本帖最后由 mfh 于 2012-1-17 17:24 编辑 ]