(基于C++语言实现)
本文由CSDN-蚍蜉撼青松 【主页:http://blog.csdn.net/howeverpf】原创,转载请注明出处!
在MIME格式的电子邮件中,base64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本。使用时,在传输编码方式中指定base64。使用的字符包括大小写字母各26个,加上10个数字,和加号“+”,斜杠“/”,一共64个字符,等号“=”用来作为后缀用途。完整的base64定义可见RFC 1421和RFC 2045。
----------------------------本段引自维基百科:http://zh.wikipedia.org/wiki/Base64
Base64编码的过程是把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后对于每个6Bit,在其高位再添两位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。在电子邮件中,根据RFC 822规定,每76个字符,还需要加上一个回车换行。由此可以估算编码后数据长度大约为原长的135.1%。
Base64编码的规则:
图1-1 Base64编码表(截自维基百科)
/***********************************************************/ /* 输入参数说明: */ /* src为指向存放输入内容的缓冲区指针 */ /* 输出参数说明: */ /* 返回值为指向存放输出内容的缓冲区指针 */ /***********************************************************/ char * Base64_Decode(char *src) { int n,i,j; int equal_count=0;//等号的个数 char *p=NULL; char *dst=NULL; char ch64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; n=strlen(src); if (n%4!=0)//输入不对 返回空指针 { debug(stderr,"Base64_Decode input error"); return dst; } if (*(src + n - 1) == ‘=‘) { equal_count += 1; } if (*(src + n - 2) == ‘=‘) { equal_count += 1; } for (i=0;i<n;i++) { p=strchr(ch64,src[i]);//p指向src[i]在ch64中的位置 if (!p) //没找到,为"=",不转换 break; src[i]=p-ch64;//将src[i]转换为0-63的数字 } dst=new char[n*3/4+1]; memset(dst,0,n*3/4+1); for (i=0,j=0;i<n-4;i+=4,j+=3) { dst[j]=(src[i]<<2) | ((src[i+1]&0x30)>>4); dst[j+1]=((src[i+1]&0x0F)<<4) | ((src[i+2]&0x3C)>>2); dst[j+2]=((src[i+2]&0x03)<<6) | src[i+3]; } switch (equal_count)//最后四个字符单独处理 { case 0: dst[j]=(src[n-4]<<2) | ((src[n-3]&0x30)>>4); dst[j+1]=((src[n-3]&0x0F)<<4) | ((src[n-2]&0x3C)>>2); dst[j+2]=((src[n-2]&0x03)<<6) | src[n-1]; break; case 1: dst[j]=(src[n-4]<<2) | ((src[n-3]&0x30)>>4); dst[j+1]=((src[n-3]&0x0F)<<4) | ((src[n-2]&0x3C)>>2); break; case 2: dst[j]=(src[n-4]<<2) | ((src[n-3]&0x30)>>4); break; default: break; } return dst; }
Quoted-Printable编码,通常缩写为"Q"编码,其原理是把一个8bit的字符用两个16进制数值表示,然后在前面加“=”。所以我们看到经过QP编码后的文件通常是这个样子:=B3=C2=BF=A1=C7=E5=A3= AC=C4=FA=BA=C3=A3=A1。同Base64一样,Quoted-Printable也是MIME邮件中常用的编码方式之一,一般用在电子邮件的标题。
Quoted-Printable的编码规则:
Quoted-Printable的解码规则:
本小节部分内容参考:
《Quote Printable编码原理(Delphi)》http://blog.csdn.net/fengsh998/article/details/8663046
《QP(Quote-Printable) 编码》http://love-love-l.blog.163.com/blog/static/2107830420113593541737/
/***********************************************************/ /* 输入参数说明: */ /* pSrc为指向存放输入内容的缓冲区指针 */ /* pDst为指向存放输出内容的缓冲区指针 */ /* nSrcLen为输入缓冲区的大小 */ /* 输出参数说明: */ /* 返回值为输出内容的大小 */ /***********************************************************/ int Quoted_Decode(char* pszSrc, char* pszDst, int nSrclen) { int i=0; int nDstLen; // 输出的字符计数 while (i< nSrclen) { if (strncmp(pszSrc, "=\r\n", 3) == 0) // 软回车,跳过 { pszSrc += 3; i+= 3; } else { if (*pszSrc == ‘=‘) // 编码字节 { sscanf(pszSrc, "=%02X", (unsigned int*)pszDst); pszDst++; pszSrc += 3; i+= 3; } else // 非编码字节 { *pszDst++ = *pszSrc++; i++; } nDstLen++; } } *pszDst = ‘\0‘; // 输出加个结束符 return nDstLen; }
这种编码方式由于最初用于使URL符合RFC 1738规范【RFC 1738中规定: “只有字母和数字[0-9,a-z,A-Z]、一些特殊符号“$-_.+!*‘(),”[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。”】而被称为URL编码,应该算是HTTP请求报文中最常见的编码了。
URL编码的编码规则:
URL编码的解码规则:
/***********************************************************/ /* 输入参数说明: */ /* pSrc为指向存放输入内容的缓冲区指针 */ /* pDst为指向存放输出内容的缓冲区指针 */ /* nSrcLen为输入缓冲区的大小 */ /* 输出参数说明: */ /* 返回值为输出内容的大小 */ /***********************************************************/ int Url_Decode(const char *pSrc, char *pDst, int nSrcLen) { int nDstLen; // 输出的字符计数 int i=0; while(i < nSrcLen) { if(*pSrc == ‘%‘) // 是编码字节 { sscanf(pSrc, "%%%02x", (unsigned short *)pDst); pDst++; pSrc += 3; i += 3; } else // 非编码字节 { *pDst++ = (unsigned char )*pSrc++; i++; } nDstLen++; } *pDst = ‘\0‘; // 输出加个结束符 return nDstLen; }
------本文由CSDN-蚍蜉撼青松【主页:http://blog.csdn.net/howeverpf】原创,转载请注明出处!------
网络协议中常见编码的原理及其解码函数的C++实现,布布扣,bubuko.com
原文:http://blog.csdn.net/howeverpf/article/details/19407111