这个礼拜忙着写一个支持POP3协议邮件服务器上的邮件收取的服务器端程序,今天总算是基本写完了。累是累了些,不过觉得还是蛮有意思的,准备总结下心得:
既然是支持POP3协议的,那么首先应该先了解什么是POP3协议,可以在我的前一篇文章里了解。
我们可以知道当用RETR [MsgNumber]命令之后可以得到指定信件的全部文本,的出来的文本类似于下面的这些:
+OK 6107 octets
Received: from darkstar.example.net (unknown [218.18.95.185])
by mx10 (Coremail) with SMTP id QkCTeaCQPUI82PkA.1
for <coolzlay@163.com>; Sun, 20 Mar 2005 23:03:04 +0800 (CST)
X-Originating-IP: [218.18.95.185]
Received: from tencent.com ([192.168.21.75])
by darkstar.example.net (8.12.8/8.12.4) with SMTP id j2KD0XTI019175
for <coolzlay@163.com>; Sun, 20 Mar 2005 21:00:33 +0800
Date: Sun, 20 Mar 2005 21:00:33 +0800
Message-Id: <200503201300.j2KD0XTI019175@darkstar.example.net>
Subject:=?GB2312?B?vrq829POz7fQ/bfnvfjPriDN8tSqvbHGt8vmyta/ybXDPT09PWhtc2VzYml6bHhlem5mbHBlcGlw?=
From: service@tencent.com
To: coolzlay@163.com
Cc:
Content-Type: text/html; charset=gb2312
--=====003_Dragon655344641743_=====
Content-Type: text/plain;
charset="gbk"
Content-Transfer-Encoding: base64
xNzOqtGn0KPV+bniIM7Suty439DLPGJyPjwhLS0gZm9vdGVyIC0tPjxicj48YnI+PGJyPgo8
.
如果细心观察就可以发现这里面包含了很多描述该封信件的信息,如果还有什么不了解的可以去看看关于RFM-1522协议,其中会看到关于编码的问题,其中我们也可以看出信件的描述信息的编码并不和信件正文一样所以应该分开来解码
比如信件的描述信息标题 subject
Subject: :=?GB2312?B?vrq829POz7fQ/bfnvfjPriDN8tSqvbHGt8vmyta/ybXDPT09PWhtc2VzYml6bHhlem5mbHBlcGlw?=
可以看出2个?之间的字符就是他的编码字符集,所以先获得编码字符集在解出来
下面是我给出的解法
public static byte[] GetByteArray(string s)
{
byte[] buffer=new byte[s.Length];
int bufferPosition=0;
if (s.Length>1)
{
for(int i=0;i<s.Length;i++)
{
if (s[i]=='=')
{
if (s[i+1]=='/r' && s[i+2]=='/n')
bufferPosition--;
else
buffer[bufferPosition]=System.Convert.ToByte(s.Substring(i+1,2),16);
i+=2;
}
else if (s[i]=='_')
buffer[bufferPosition]=32;
else
buffer[bufferPosition]=(byte)s[i];
bufferPosition++;
}
}
else
{
buffer[bufferPosition]=32;
}
byte[] newArray=new byte[bufferPosition];
Array.Copy(buffer,newArray,bufferPosition);
return newArray;
}
public static string DecodeOne(string s)
{
char[] separator={'?'};
string[] sArray=s.Split(separator);
if (sArray[0].Equals("=")==false)
return s;
byte[] bArray;
if (sArray[2].ToUpper()=="Q") //querystring
bArray=GetByteArray(sArray[3]);
else if (sArray[2].ToUpper()=="B")//base64
bArray=Convert.FromBase64String(sArray[3]);
else
return s;
Encoding encoding=Encoding.GetEncoding(sArray[1]);
return encoding.GetString(bArray);
}
public static string Decode(string s)
{
StringBuilder retstring=new StringBuilder();
int old=0,start=0,stop;
for(;;)
{
start=s.IndexOf("=?",start);
if (start==-1)
{
retstring.Append(s,old,s.Length-old);
return retstring.ToString();
}
stop=s.IndexOf("?=",start+2);
if (stop==-1) //blad w stringu
return s;
retstring.Append(s,old,start-old);
retstring.Append(DecodeOne(s.Substring(start,stop-start+2)));
start=stop+2;
old=stop+2;
}
}
只要调用
string Tex="=?GB2312?B?vrq829POz7fQ/bfnvfjPriDN8tSqvbHGt8vmyta/ybXDPT09PWhtc2VzYml6bHhlem5mbHBlcGlw?=";
Console.WriteLine(Decode(Tex));
就可以看到汉字了 呵呵