QuotedPrintable解码

最近在修改一个开源POP3客户端框架时,碰到了QuotedPrintable乱码的问题,原框架是老外写的,没有考虑到中文的情况。因此在对QuotedPrintable编码的内容进行解码时,是逐个字符进行转换的,英文的当然不会有任何问题。于是在网上搜了一下,发现基于C#的QuotedPrintable解码的代码很少,找到的大部分都是转帖,而且大部分都是采用默认的Encoding进行解码,前提是用了他们自己写的编码方式才能解码。这当然不符合我的要求,既然作为POP3客户端,收到的邮件都是来自不同的服务器,编码方式是动态变化的。

于是只能自己动手去解决,在对原始邮件内容(QuotedPrintable加密的内容)解析时,碰到的主要问题是一个中文字符由多个字节组成,如果字节取得不正确或没有取完整,那么只能解码一部分,会出现个别文字乱码的情况。网上提供的清一色代码都是用字符串截取的方式,但是这种方式不够保险,总会出现截取不完整的情况,或者完全失效。参考开源POP3客户端框架作者采用的正则匹配替换方式,采用替换的方式最为保险。

基本实现方式是,匹配出多个QuotedPrintable编码的内容,比如得到=4F=B5=9F=AB,然后再分解得到单个编码内容如=4F,这样为一个字节的内容,将多个字节放在一个数组,得到一个完整的byte[],接下来就是用对应的编码方式getstring即可。用得到的string替换编码内容,达到解码的方式。

 

ExpandedBlockStart.gif QuotedPrintable解码实现
 1           private   const   string  QpSinglePattern  =   " (\\=([0-9A-F][0-9A-F])) " ;
 2 
 3           private   const   string  QpMutiplePattern  =   @" ((\=[0-9A-F][0-9A-F])+=?\s*)+ " ;
 4 
 5           public   static   string  Decode( string  contents, Encoding encoding)
 6          {
 7               if  (contents  ==   null )
 8              {
 9                   throw   new  ArgumentNullException( " contents " );
10              }
11 
12               //  替换被编码的内容
13               string  result  =  Regex.Replace(contents, QpMutiplePattern,  new  MatchEvaluator( delegate (Match m)
14              {
15                  List < byte >  buffer  =   new  List < byte > ();
16                   //  把匹配得到的多行内容逐个匹配得到后转换成byte数组
17                  MatchCollection matches  =  Regex.Matches(m.Value, QpSinglePattern, RegexOptions.IgnoreCase  |  RegexOptions.Compiled);
18                   foreach  (Match match  in  matches)
19                  {
20                      buffer.Add(( byte )HexToByte(match.Groups[ 2 ].Value.Trim()));
21                  }
22                   return  encoding.GetString(buffer.ToArray());
23              }), RegexOptions.IgnoreCase  |  RegexOptions.Compiled);
24 
25               //  替换多余的链接=号
26              result  =  Regex.Replace(result,  @" =\s+ " "" );
27 
28               return  result;
29          }
30 
31           private   static   int  HexToByte( string  hex)
32          {
33               int  num1  =   0 ;
34               string  text1  =   " 0123456789ABCDEF " ;
35               for  ( int  num2  =   0 ; num2  <  hex.Length; num2 ++ )
36              {
37                   if  (text1.IndexOf(hex[num2])  ==   - 1 )
38                  {
39                       return   - 1 ;
40                  }
41                  num1  =  (num1  *   0x10 +  text1.IndexOf(hex[num2]);
42              }
43               return  num1;
44          }

 

 

转载于:https://www.cnblogs.com/shenba/archive/2010/06/19/1761085.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值