BASE64算法

来源:互联网 发布:知乎top50 编辑:程序博客网 时间:2024/06/06 00:54


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=2200100101000101010000011100010110xx100101xx010101xx000111xx010110100101010101000111010110l=37V=21H=7W=22


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


011001010111010101011000euX




应用:

需要明文保存二进制数据时,可以将不可打印的二进制数据经过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 #endifconst 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
原创粉丝点击