【问题标题】:Decode quoted printable correct解码引用可打印正确
【发布时间】:2012-05-14 15:43:44
【问题描述】:

我有以下字符串:

=?utf-8?Q?=5Bproconact_=2D_Verbesserung_=23=32=37=39=5D_=28Neu=29_Stellvertretungen_Benutzerrecht_=2D_andere_k=C3=B6nnen_f=C3=BCr_andere_Stellvertretungen_erstellen_=C3=A4ndern_usw=2E_dadurch_ist_der_Schutz_der_Aktivi=C3=A4ten_Mails_nicht_gew=C3=A4hrt=...

这是一种编码

[proconact-Verbesserung #279] (Neu) Stellvertretungen Benutzerrecht - andere können für andere Stellvertretungen erstellen ändern usw. dadurch ist der Schutz der Aktiviäten Mails nicht gewährt.

我正在寻找一种方法来解码引用的字符串。

我试过了:

private static string DecodeQuotedPrintables(string input, string charSet) {
    Encoding enc = new ASCIIEncoding();
    try {
        enc = Encoding.GetEncoding(charSet);
    } catch {
        enc = new UTF8Encoding();
    }

    var occurences = new Regex(@"(=[0-9A-Z]{2}){1,}", RegexOptions.Multiline);
    var matches = occurences.Matches(input);

    foreach (Match match in matches) {
        try {
            byte[] b = new byte[match.Groups[0].Value.Length / 3];
            for (int i = 0; i < match.Groups[0].Value.Length / 3; i++) {
                b[i] = byte.Parse(match.Groups[0].Value.Substring(i * 3 + 1, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
            }
            char[] hexChar = enc.GetChars(b);
            input = input.Replace(match.Groups[0].Value, hexChar[0].ToString());
        } catch { ;}
    }
    input = input.Replace("?=", "").Replace("=\r\n", "");

    return input;
}

当我打电话时(其中 s 是我的字符串)

var x = DecodeQuotedPrintables(s, "utf-8");

这将返回

=?utf-8?Q?[proconact_-_Verbesserung_#_(Neu)_Stellvertretungen_Benutzerrecht_-_andere_können_für_andere_Stellvertretungen_erstellen_ändern_usw._dadurch_ist_der_Schutz_der_Aktiviäten_Mails_nicht_gewährt=...

我该怎么做,_ 和开头的 =?utf-8?Q? 和结尾的 =.. 也会被删除?

【问题讨论】:

  • 这是邪恶的:try { ... } catch { ;}
  • 你最终应该得到什么?您要从原始字符串中取出的最后一个字符串是什么?
  • 这是我应该得到的原始字符串:[proconact-Verbesserung #279] (Neu) Stellvertretungen Benutzerrecht - andere können für andere Stellvertretungen erstellen ändern usw。 dadurch ist der Schutz der Aktiviäten Mails nicht gewährt.
  • 附注:您的源字符串看起来像一个 *** 的 url 编码字符串,如果它没有被替换为 url 编码的实体(如 %23),它可以很容易地被解码与_=23_。如果您无法控制源字符串,可能会取消替换源字符串并进行 url 解码,这将大大简化您的方法。
  • @Filburt:源字符串是有效的(几乎)RFC 2047 编码字;请参阅下面的答案。

标签: c# .net


【解决方案1】:

您尝试解码的文本通常位于 MIME 标头中,并根据以下 Internet 标准中定义的规范进行编码:RFC 2047: MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text

在 GitHub 上有这样一个解码器的示例实现;也许你可以从中汲取一些想法:RFC2047 decoder in C#.

您还可以使用此在线工具来比较您的结果:Online MIME Headers Decoder

请注意,您的示例文本不正确。规范声明:

encoded-word = "=?" charset "?" encoding "?" encoded-text "?="

根据规范,任何编码字必须?=结尾。因此,您的样本必须从以下方面进行更正:

=?utf-8?Q?=5Bproconact_=2D_Verbesserung_=23=32=37=39=5D_=28Neu=29_Stellvertretungen_Benutzerrecht_=2D_andere_k=C3=B6nnen_f=C3=BCr_andere_Stellvertretungen_erstellen_=C3=A4ndern_usw=2E_dadurch_ist_der_Schutz_der_Aktivi=C3=A4ten_Mails_nicht_gew=C3=A4hrt=

…to(滚动到最右边):

=?utf-8?Q?=5Bproconact_=2D_Verbesserung_=23=32=37=39=5D_=28Neu=29_Stellvertretungen_Benutzerrecht_=2D_andere_k=C3=B6nnen_f=C3=BCr_andere_Stellvertretungen_erstellen_=C3=A4ndern_usw=2E_dadurch_ist_der_Schutz_der_Aktivi=C3=A4ten_Mails_nicht_gew=C3=A4hrt?=

严格来说,您的样本也是无效的,因为它超过了对任何编码词施加的 75 个字符的限制;然而,大多数解码器倾向于容忍这种不一致。

【讨论】:

    【解决方案2】:

    我已经测试了 5+ 的代码 sn-ps,这是有效的:我修改了正则表达式部分:

    测试线:

        im sistemlerimizde bak=FDm =E7al=FD=FEmas=FD yap=FDlaca=F0=FDndan; www.gib.=
    

    示例调用:

        string encoding = "windows-1254";
        string input = "im sistemlerimizde bak=FDm =E7al=FD=FEmas=FD yap=FDlaca=F0=FDndan; www.gib.=";
        DecodeQuotedPrintables(input, encoding);
    

    代码 sn-p:

        private static string DecodeQuotedPrintables(string input, string charSet)
        {
    
    
            System.Text.Encoding enc = System.Text.Encoding.UTF7;
    
            try
            {
                enc = Encoding.GetEncoding(charSet);
            }
            catch
            {
                enc = new UTF8Encoding();
            }
    
    
    
            ////parse looking for =XX where XX is hexadecimal
            //var occurences = new Regex(@"(=[0-9A-Z]{2}){1,}", RegexOptions.Multiline);
            var occurences = new Regex("(\\=([0-9A-F][0-9A-F]))", RegexOptions.Multiline);
            var matches = occurences.Matches(input);
    
            foreach (Match match in matches)
            {
                try
                {
                    byte[] b = new byte[match.Groups[0].Value.Length / 3];
                    for (int i = 0; i < match.Groups[0].Value.Length / 3; i++)
                    {
                        b[i] = byte.Parse(match.Groups[0].Value.Substring(i * 3 + 1, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
                    }
                    char[] hexChar = enc.GetChars(b);
                    input = input.Replace(match.Groups[0].Value, hexChar[0].ToString());
                }
                catch
                { ;}
            }
            input = input.Replace("?=", "").Replace("=\r\n", "");
    
            return input;
        }
    

    【讨论】:

      【解决方案3】:

      正如standard class .NET 所述,就是为此目的而存在的。

      string unicodeString =
                  "=?UTF-8?Q?YourText?=";
              System.Net.Mail.Attachment attachment = System.Net.Mail.Attachment.CreateAttachmentFromString("", unicodeString);
              Console.WriteLine(attachment.Name);
      

      【讨论】:

        【解决方案4】:

        根据我的评论,我建议

        private static string MessedUpUrlDecode(string input, string encoding)
        {
            Encoding enc = new ASCIIEncoding();
        
            try
            {
                enc = Encoding.GetEncoding(charSet);
            }
            catch
            {
                enc = new UTF8Encoding();
            }
        
            string messedup = input.Split('?')[3];
            string cleaned = input.Replace("_", " ").Replace("=...", ".").Replace("=", "%");
        
            return System.Web.HttpUtility.UrlDecode(cleaned, enc);
        }
        

        假设源字符串的切割是一致的。

        【讨论】:

          【解决方案5】:

          我不太确定如何删除

          =?utf-8?Q?
          

          除非它一直出现,否则你可以这样做:

          input = input.Split('?')[3];
          

          要删除尾随的“=”,您可以通过以下方式将其删除:

          input = input.Remove(input.Length - 1);
          

          您可以通过用空格替换“_”来摆脱它:

          input = input.Replace("_", " ");
          

          您可以在 DecodeQuotedPrintables 函数中使用这些代码。

          希望对您有所帮助!

          【讨论】:

            猜你喜欢
            • 2020-03-16
            • 2013-12-14
            • 2012-10-12
            • 2012-02-06
            • 2019-11-23
            • 2019-11-25
            • 2013-06-22
            • 2012-10-19
            • 2015-11-18
            相关资源
            最近更新 更多