C#中对POP3邮件解码

Base64和下面将要介绍的Quoted-Printable都属于MIME(多部分( multi-part)、多媒体电子邮件和 WWW 超文本的一种编码标准,用于传送诸如图形、声音和传真等非文本数据)。MIME定义在RFC1341中。

    Base64是现今在互联网上应用最多的一种编码,几乎所有的电子邮件软件头把它作为默认的二进制编码,它已经成了现今电子邮件编码的代名词。


    下面是Base64的一个例子,从例子中,您也可以看到Base64与电子邮件的的紧密联系:
Content-Type: text/plain;charset="cn-gb"
Content-Transfer-Encoding: BASE64
CQkJICAgIKG2wtLC68vjt6i088irobcNCgnX99XfOm1vZ2Fvo6yw19TGu8a619W+o6h0ZWxuZXQ6


Ly8yMDIuMTEyLjIwLjEzMjoyM6Ops8nUsaGjDQoJICAgICAgxKq438jtvP65pNf3ytKjumh0dHA6


Ly9tb2dhby5iZW50aXVuLm5ldA0KCQkJRW1haWx0bzptb2dhb0AzNzEubmV0DQoJICAgKioqKioq


KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICAgICAgICAgICAgICAgDQoJ


ICAgKiCz/cHLvMfS5Mqyw7S2vLK7tPjX36Oss/3By9fjvKPKssO0tryyu8H0z8IqDQoJICAgKioq


KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq


    你可以把它单独存成一个文件,可以取名为:mogao.eml,双击可以用OutLook打开(前两行为邮件的原始信息,从第四行开始为编码内容)。
    Base64的算法同Uuencode的算法很接近,也很简单:它将字符流顺序放入一个 24 位的缓冲区,缺字符的地方补零。然后将缓冲区截断成为 4 个部分,高位在先,每个部分 6 位,用下面的64个字符重新表示:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
wxyz0123456789+/"。如果输入只有一个或两个字节,那么输出将用等号"="补足。
这可以隔断附加的信息造成编码的混乱。它每行一般为76个字符。
    下面我给出Base64的编码和解码的C语言描述:
/*Base64编码*/
void Base64(unsigned char chasc[3],unsigned char chuue[4])
/*
  chasc:未编码的二进制代码
  chuue:编码过的Base64代码
*/
{
 int i,k=2;
 unsinged char t=NULL;
 for(i=0;i<3;i++)
 {
  *(chuue+i)=*(chasc+i)>>k;
  *(chuue+i)|=t;
  t=*(chasc+i)<<(8-k);
  t>>=2;
  k+=2;
 }
 *(chuue+3)=*(chasc+2)&63;
 for(i=0;i<4;i++)
    if((*(chuue+i)>=0)&&(*(chuue+i)<=25)) *(chuue+i)+=65;
    else if((*(chuue+i)>=26)&&(*(chuue+i)<=51)) *(chuue+i)+=71;
    else if((*(chuue+i)>=52)&&(*(chuue+i)<=61)) *(chuue+i)-=4;
    else if(*(chuue+i)==62) *(chuue+i)=43;
    else if(*(chuue+i)==63) *(chuue+i)=47;
}
/*Base64解码*/
void unBase64(unsigned char chuue[4],unsigned char chasc[3])
/*
chuue:未解码的Base64代码
chasc:解码过的二进制代码
*/
{int i,k=2;
 unsigned char t=NULL;
 for(i=0;i<4;i++)
     if((*(chuue+i)>=65)&&(*(chuue+i)<=90)) *(chuue+i)-=65;
     else if((*(chuue+i)>=97)&&(*(chuue+i)<=122)) *(chuue+i)-=71;
     else if((*(chuue+i)>=48)&&(*(chuue+i)<=57)) *(chuue+i)+=4;
     else if(*(chuue+i)==43) *(chuue+i)=62;
     else if(*(chuue+i)==47) *(chuue+i)=63;
     else if(*(chuue+i)==61) *(chuue+i)=0;
 for(i=0;i<3;i++)
 {*(chhex+i)=*(chuue+i)<<k;
  k+=2;
  t=*(chuue+i+1)>>8-k;
  *(chhex+i)|=t;
 }
}
4. Quoted-Printable
    Quoted-Printable简称QP, 一般用在Email系统中。它
通常用于少量文本方式的8位字符的编码,例如Foxmail就用
它做对主题和信体的编码。这种编码的应该是很好辨认的:
它有大量的"="。下面是它的一个例子:
Mime-Version: 1.0
Content-Transfer-Encoding: quoted-printable
                            =A1=B6=C2=D2=C2=EB=CB=E3=B7=A8=B4=F3=C8=AB=A1=B7
        =D7=F7=D5=DF:mogao=A3=AC=B0=D7=D4=C6=BB=C6=BA=D7=D5=BE=A3=A8telnet://202.11
2.20.132:23=A3=A9=B3=C9=D4=B1=A1=A3
              =C4=AA=B8=DF=C8=ED=BC=FE=B9=A4=D7=F7=CA=D2=A3=BAhttp://mogao.bentiun.
net
                        Emailto:mogao@371.net
           *********************************************
           * =B3=FD=C1=CB=BC=C7=D2=E4=CA=B2=C3=B4=B6=BC=B2=BB=B4=F8=D7=DF=A3=AC=B3=
FD=C1=CB=D7=E3=BC=A3=CA=B2=C3=B4=B6=BC=B2=BB=C1=F4=CF=C2*
           *********************************************
    你可以把它单独存成一个文件,取名为:mogao.eml,双击可以用OutLook打开(前两行为邮件的原始信息,从第四行开始为编码内容)。
    QP的算法可以说是最简单的也可以说是编码效率最低的(它的编码率是1:3),它是专门为了处理8位字符制定的。它的算法是:读一个字符,如果ASCII码大于127,即字符的第8位是1的话,进行编码,否则忽略(有时也对7位字符编码)。
编码很简单,看下面的C语言描述即可:
/*QP编码*/
void qp(unsigned char sour,unsigned char first,unsigned char second)
/*
  sour:要编码的字符
  first:编码后的第一个字符
   second:编码后的第二个字符
  first和second为返回值
*/
{
 if(sour>127)
 {first=sour>>4;
  second=sour&15;
  if(first>9) first+=55;
  else first+=48;
  if(second>9) second+=55;
  else second+=48;
  printf("%c%c%c",'=',first,second);
 }
}
/*QP解码*/
void uqp(unsigned char sour,unsigned char first,unsigned char second)
/*
  sour:解码后的字符
  first:QP码的第一个字符
   second:QP码的第二个字符
  sour为返回值
*/
{
 if(first>=65) first-=55;
 else first-=48;
 if(second>=65) second-=55;
 else second-=48;
 sour=NULL;
 sour=first<<4;
 sour|=second;
}
    现在大家知道为什么QP的编码率那么低了吧!关于QP的详细说明和准确定义可以参阅RFC2045。


About this Entry

This page contains a single entry by Sky published on July 28, 2005 4:59 PM.

将DBF,XLS,XML,MDB文件导入C#DataGrid的方法 was the previous entry in this blog.

2进制、8进制、10进制、16进制...各种进制间的轻松转换 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.