首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# POP3 郵件 MIME Base64 解碼:提取 HTML/純文本正文

     編輯:程式設計綜合問答

郵件結構分析

Content-Type: multipart/mixed; boundary="----=..."
// 部分 1: text/plain; charset="gb18030"; encoding=base64
// 部分 2: text/html;  charset="gb18030"; encoding=base64

解碼步驟

  1. 按 boundary 分割多部分。
  2. 解析每部分 Header,獲取 Content-Transfer-Encoding、charset。
  3. Body 解碼:Base64 → Byte[] → Encoding.GetString(Byte[])。
  4. 優先選擇 text/html,回退 text/plain。

完整代碼

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

public static string DecodePop3Body(string rawMessage) {
    // 1. 獲取 boundary
    var boundaryMatch = Regex.Match(rawMessage, @"boundary=""([^""]+)""");
    if (!boundaryMatch.Success) return DecodeSinglePart(rawMessage);

    string boundary = "--" + boundaryMatch.Groups[1].Value;
    var parts = rawMessage.Split(new[] { boundary }, StringSplitOptions.RemoveEmptyEntries);

    string html = null, plain = null;
    foreach (var part in parts) {
        var headerEnd = part.IndexOf("\r\n\r\n");
        if (headerEnd < 0) continue;
        string header = part.Substring(0, headerEnd);
        string body = part.Substring(headerEnd + 4).TrimEnd('\r', '\n', '-');

        // 解析 encoding & charset
        var encMatch = Regex.Match(header, @"Content-Transfer-Encoding:\s*(\w+)", RegexOptions.IgnoreCase);
        var charsetMatch = Regex.Match(header, @"charset\s*=\s*[""']?([^""'\s;]+)", RegexOptions.IgnoreCase);
        var typeMatch = Regex.Match(header, @"Content-Type:\s*([^;]+)", RegexOptions.IgnoreCase);

        string encoding = encMatch.Success ? encMatch.Groups[1].Value.ToLower() : "7bit";
        string charset = charsetMatch.Success ? charsetMatch.Groups[1].Value : "utf-8";
        string type = typeMatch.Success ? typeMatch.Groups[1].Value.Trim().ToLower() : "text/plain";

        string decoded = DecodeContent(body, encoding, charset);

        if (type == "text/html") html = decoded;
        else if (type == "text/plain") plain = decoded;
    }
    return html ?? plain ?? "";
}

static string DecodeContent(string body, string encoding, string charset) {
    Encoding enc = Encoding.GetEncoding(charset);
    byte[] bytes;
    if (encoding == "base64") bytes = Convert.FromBase64String(body);
    else if (encoding == "quoted-printable") bytes = QuotedPrintableDecode(body);
    else bytes = enc.GetBytes(body);  // 7bit/8bit
    return enc.GetString(bytes);
}

static byte[] QuotedPrintableDecode(string input) {
    using (var ms = new MemoryStream()) {
        for (int i = 0; i < input.Length; i++) {
            char c = input[i];
            if (c == '=' && i + 2 < input.Length) {
                string hex = input.Substring(i + 1, 2);
                if (byte.TryParse(hex, System.Globalization.NumberStyles.HexNumber, null, out byte b)) {
                    ms.WriteByte(b);
                    i += 2;
                    continue;
                }
            }
            ms.WriteByte((byte)c);
        }
        return ms.ToArray();
    }
}

推薦庫

  • MimeKit:標準化 MIME 解析,自動處理編碼、邊界、嵌套。var message = MimeMessage.Load(stream);
  • OpenPop.NET:專注 POP3 客戶端,內建 MIME 解析。

編碼陷阱

問題解決
gb18030 不識別.NET Core 需註冊 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance) (NuGet: System.Text.Encoding.CodePages)
Base64 換行符干擾解碼前 body.Replace("\r\n", "").Replace("\n", "")
多層嵌套 multipart遞歸解析 boundary,或直接用 MimeKit
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved