zoukankan      html  css  js  c++  java
  • QuotedPrintable解码

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

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

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

    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         }
  • 相关阅读:
    Windows CE下拨号上网
    JS验证示例
    Automation server can't create object , AUTOMATION服务器无法创建对象
    使用企业库调用存储过程(带参数)完成数据获取样例
    hibernate 一对多 多对一 关系表 增删改查大礼包ps二级查也有
    游戏服务器架构
    游戏中的加密算法
    二进制高效位运算
    游戏网络知识
    复习hiernate
  • 原文地址:https://www.cnblogs.com/shenba/p/1761085.html
Copyright © 2011-2022 走看看