如何转换Quoted-Print字符串

时间:2016-05-31 08:09:29

标签: c# vb.net mime quoted-printable

我正在研究.NET中的French String 解码邮件正文,我收到“Chasn = C3 = A9 sur illet” 我想得到“Chasnésurillet” 我在2天的网络搜索中找不到任何解决方案。

C#ou VB.NET 任何人都可以帮助我吗?

谢谢

5 个答案:

答案 0 :(得分:0)

这是UTF8编码。

使用这篇文章:

http://www.dpit.co.uk/decoding-quoted-printable-email-in-c/

这是代码(如果有帮助,别忘了接受答案):

using System;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine(DecodeQuotedPrintable("Chasn=C3=A9 sur illet"));
            Console.ReadKey();
        }

        static string DecodeQuotedPrintable(string input)
        {
            var occurences = new Regex(@"(=[0-9A-Z][0-9A-Z])+", RegexOptions.Multiline);
            var matches = occurences.Matches(input);
            foreach (Match m in matches)
            {
                byte[] bytes = new byte[m.Value.Length / 3];
                for (int i = 0; i < bytes.Length; i++)
                {
                    string hex = m.Value.Substring(i * 3 + 1, 2);
                    int iHex = Convert.ToInt32(hex, 16);
                    bytes[i] = Convert.ToByte(iHex);
                }
                input = input.Replace(m.Value, Encoding.UTF8.GetString(bytes));
            }
            return input.Replace("=rn", "");
        }
    }
}

答案 1 :(得分:0)

来自:https://stackoverflow.com/a/36803911/6403521 我的解决方案:

    [TestMethod]
    public void TestMethod1()
    {

        Assert.AreEqual("La Bouichère", quotedprintable("La Bouich=C3=A8re", "utf-8"));
        Assert.AreEqual("Chasné sur illet", quotedprintable("Chasn=C3=A9 sur illet", "utf-8"));
        Assert.AreEqual("é è", quotedprintable("=C3=A9 =C3=A8", "utf-8"));
    }
    private string quotedprintable(string pStrIn, string encoding)
    {
        String strOut = pStrIn.Replace("=\r\n", "");
        // Find the first =
        int position = strOut.IndexOf("=");
        while (position != -1)
        { 
            // String before the =
            string leftpart = strOut.Substring(0, position);
            // get the QuotedPrintable String in a ArrayList
            System.Collections.ArrayList hex = new System.Collections.ArrayList();
            // The first Part
            hex.Add(strOut.Substring(1 + position, 2));
            // Look for the next parts
            while (position + 3 < strOut.Length && strOut.Substring(position + 3, 1) == "=")
            {
                position = position + 3;
                hex.Add(strOut.Substring(1 + position, 2));
            }
            // In the hex Array, we have two items 
            // Convert using the GetEncoding Function
            byte[] bytes = new byte[hex.Count];
            for (int i = 0; i < hex.Count; i++)
            {
                bytes[i] = System.Convert.ToByte(new string(((string)hex[i]).ToCharArray()), 16);
            }
            string equivalent = System.Text.Encoding.GetEncoding(encoding).GetString(bytes);
            // Part of the orignal String after the last QP Symbol
            string rightpart = strOut.Substring(position + 3);
            // Re build the String
            strOut = leftpart + equivalent + rightpart;
            // find the new QP Position
            position = leftpart.Length + equivalent.Length;
            if (rightpart.Length == 0)
            {
                position = -1;
            }
            else
            {
                position = strOut.IndexOf("=", position + 1);
            }
        }
        return strOut;
    }

答案 2 :(得分:0)

或者最简单的方法,只需使用QuotedPrintableDecoder库中的MimeKit

static string DecodeQuotedPrintable (string input, string charset)
{
    var decoder = new QuotedPrintableDecoder ();
    var buffer = Encoding.ASCII.GetBytes (input);
    var output = new byte[decoder.EstimateOutputLength (buffer.Length)];
    int used = decoder.Decode (buffer, 0, buffer.Length, output);
    var encoding = Encoding.GetEncoding (charset);
    return encoding.GetString (output, 0, used);
}

请注意,上面的其他答案假设解码的内容将是ASCII或UTF-8,但情况并非如此。您需要从正在解码的MIME部分的charset标题中获取Content-Type参数。

当然......如果您不知道如何获取该信息,您可以简单地使用我的真棒MailKit库从IMAP获取MIME部分并让它完成所有这些工作你。

答案 3 :(得分:0)

我们遇到了这种方法的问题 - 它非常慢。 以下增强性能A LOT

public static string FromMailTransferEncoding(this string messageText, Encoding enc, string transferEncoding)
{
    if (string.IsNullOrEmpty(transferEncoding)) 
        return messageText;

    if ("quoted-printable".Equals(transferEncoding.ToLower())) 
    {
        StringBuilder sb = new StringBuilder();               
        string delimitorRegEx = @"=[\r][\n]";
        string[] parts = Regex.Split(messageText, delimitorRegEx);

        foreach (string part in parts)
        {
            string subPart = part;
            Regex occurences = new Regex(@"(=[0-9A-Z][0-9A-Z])+", RegexOptions.Multiline);
            MatchCollection matches = occurences.Matches(subPart);

            foreach (Match m in matches)
            {
                byte[] bytes = new byte[m.Value.Length / 3];
                for (int i = 0; i < bytes.Length; i++)
                {
                    string hex = m.Value.Substring(i * 3 + 1, 2);
                    int iHex = Convert.ToInt32(hex, 16);
                    bytes[i] = Convert.ToByte(iHex);
                }

                subPart = occurences.Replace(subPart, enc.GetString(bytes), 1);
            }

            sb.Append(subPart);
        }
        return sb.ToString();
    }        
return messageText;
}

答案 4 :(得分:-1)

    static string ConverFromHex(string source)
    {
        string target = string.Empty;

        int startPos = source.IndexOf('=', 0);
        int prevStartPos = 0;
        while (startPos >= 0)
        {
            // concat with substring from source
            target += source.Substring(prevStartPos, startPos - prevStartPos);

            // next offset
            startPos++;

            // update prev pos
            prevStartPos = startPos;

            // get substring
            string hexString = source.Substring(startPos, 2);

            // get int equiv
            int hexNum = 0;
            if (int.TryParse(hexString, System.Globalization.NumberStyles.AllowHexSpecifier, System.Globalization.CultureInfo.InvariantCulture, out hexNum))
            {
                // add to target string
                target += (char)hexNum;

                // add hex length
                prevStartPos += 2;
            }

            // next occurence
            startPos = source.IndexOf('=', startPos);
        }

        // add rest of source
        target += source.Substring(prevStartPos);

        return target;
    }