BASE64算法


Base64与MD5算法有着同样的位置,因为电子邮箱(e-mail)正文就是base64编码的。


Base64实现了将任意字节转为可读字符的编码。

按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.) 
ASCII码表如下:





图片、压缩文件、程序等等都是二进制文件,这些文件一样以字节为单位存储数据,这些字节往往不仅仅是2的7次方以内的可显示的文字字符编码,还有可能是大于127(有符号数小于0)的字节,这些字节没办法用字符显示出来,Base64就是通过某种算法将他们显示出来。


这是一种可逆的编码方式。


编码后的数据是一个字符串,其中包含的字符为:A-Z、a-z、0-9、+、/共64个字符。

【注:其实是65个字符,“=”是填充字符】。


64个字符需要6位来表示,表示成数值为0~63。


BASE64编码表:



这样,长度为3个字节的数据经过Base64编码后就变为4个字节。

例:

字符串“Xue”经过Base64编码后参照BASE64编码表可表示为“WHVl”。



长度为3个字节的数据位数是8*3=24,可以精确地分成6*4。

如果数据的字节数不是3的倍数,则其位数就不是6的倍数,那么需要就不能精确地划分成6位的块。,

此时,需在原数据后面添加1个或2个零值字节,使其字节数是3的倍数。

然后,在编码后的字符串后面添加1个或2个等号“=”,表示所添加的零值字节数。

例:

字符串“Xu”经过Base64编码后变为“WHU=”。






字符串“X”经过Base64编码后变为“WA==”。



Base64码:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

原数据Xue在内存中的存储形式为:

左高右低



将其转换成如下形式方可进行编码:





同样:进行解码时WHVl转为base64码后(22,7,21,37)在内存中的存储形式为:

左高右低




要进行的转换:



l=37V=21H=7W=22
00100101000101010000011100010110
xx100101xx010101xx000111xx010110
100101010101000111010110
l=37V=21H=7W=22


  

010110000111010101100101
W=22H=7V=21l=37
Xue


011001010111010101011000
euX




应用:

需要明文保存二进制数据时,可以将不可打印的二进制数据经过Base64编码转成可打印的字符串。

  • Mozilla Thunderbird和Evolution用Base64来保密电子邮件密码
  • Base64也会经常用作一个简单的“加密”来保护某些数据,而真正的加密通常都比较繁琐。
  • 垃圾讯息传播者用Base64来避过反垃圾邮件工具,因为那些工具通常都不会翻译Base64的讯息。
  • LDIF档案,Base64用作编码字串。
  • 以“迅雷下载”为例: 很多下载类网站都提供“迅雷下载”的链接,其地址通常是加密的迅雷专用下载地址。
其实迅雷的“专用地址”也是用Base64加密的,其加密过程如下:
一、在地址的前后分别添加AA和ZZ
二、对新的字符串进行Base64编码
另: Flashget的与迅雷类似,只不过在第一步时加的“料”不同罢了,
Flashget在地址前后加的“料”是[FLASHGET]
而QQ旋风的干脆不加料,直接就对地址进行Base64编码了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef UCHAR
#define UCHAR unsigned char 
#endif

const char* base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static UCHAR FindPos(char c);
char* Base64Encode(char* s, int len);
char* Base64Decode(char* code);

int main(int argc, char* argv[])
{
	char msg[] = "Xue1234";
	char *encode,*decode;
	encode = Base64Encode(msg,strlen(msg));
	printf("encode:%s-><%s>\n",msg,encode);
	decode = Base64Decode(encode);
	printf("\ndecode:%s-><%s>\n",encode,decode);
	free(encode);
	free(decode);
	system("pause");
	return 0;
}
static UCHAR FindPos(char c)
{
	UCHAR p;
	for(p=0; p<strlen(base64); p++)
	{
		if(c == base64[p])
		{
			break;
		}
	}
	return p;
}


char* Base64Decode(char* s)
{
	UCHAR* decode = NULL;
	int len;
	int i,j;
	UCHAR ch;
	int unit;
	int td;
	char* pch;
	int itemp;
	len	= strlen(s);
	unit = len/4;
	//printf("---=>%s<=>%d<=>%d<---\n",s,len,unit);
	
	decode = (UCHAR*)malloc(len+1);
	
	memset(decode,'\0',len+1);
	for(i=0; i<len; i++)
	{
		ch = FindPos(s[i]);
		//printf("%d ",ch);
		decode[i]=ch;
	}
	for(i=0;i<unit; i++)
	{
		itemp = *(int*)(decode+i*4);
		//printf("\n###<%d>###\n",itemp);
		pch = (UCHAR*)&itemp;
		for(j=0;j<4;j++)
		{
			//printf("<%d>",*pch);
			*((char*)&td) = (*pch & 0x3f) << 2;
			td = td << 6;
			pch++;
		}
		td = td >> 8;
		for(j=0;j<3;j++)
		{
			decode[i*3+2-j] = td & 0xff;
			//printf("<%d>",decode[i*3+2-j]);
			td = td >> 8;
		}
		
	}
	decode[i*3] = '\0';
	return decode;
}

char* Base64Encode(char* s, int dataLen)
{
	char *encode;
	int dataCount;
	int codeSize = 0,unit;
	int i,j,temp,p=0,index,t;
	int precode=0;
	if(dataLen<1)
		{return NULL;}
	unit = dataLen/3;
	dataCount = dataLen*8/6;
	if(dataLen%3)
		{unit += 1;dataCount += 1;}
	codeSize = unit*4;
	encode = (char*)malloc(codeSize+1);
	memset(encode,'\0',codeSize+1);
	for(i=0; i<unit; i++)
	{
		temp = 0;
		//if(i*3< dataLen){
		temp = *(int*)(s+i*3) & ~(0xff<<24);
		//printf("-=-=%c-%c-%c-=%d=-=\n",*(char*)&temp,*(((char*)&temp)+1),*(((char*)&temp)+2),temp);

		for(t=0; t<3; t++)
		{
			precode = precode | (temp & 0xff);
			precode = precode << 8;
			temp = temp>>8;
		}
		for(j=0;j<4;j++)
		{
			if(p<dataCount)
			{
				index = (precode<<6*j) & 0xfc000000;
				//printf("-=%d=%x-=\n",precode,(index>>26)&0x3f);
				encode[p] = base64[(index>>26)&0x3f];
				p++;
			}
			else
			{
				encode[p] = '=';
				p++;
			}
		}
		//}

	}
	encode[codeSize] = '\0';
	return encode;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZenZenZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值