从一封注册确认邮件引出的C#中字符串不同编码格式的转换

今天在一个论坛注册了账号,注册成功之后,论坛提示已经往注册邮箱发送了一封确认邮件。去邮箱查看,邮件已经收到,但是很特别,内容是一长串的字母字符。正好想要对C#中对字符串的编码与解码做一点总结,于是以此邮件开始研究编码与解码的实现方法。

From: =?gbk?B?vvzV/snnx/g=?= <xxx@xxx.com>
MIME-Version: 1.0
Content-type: text/html; charset=gbk
Reply-To:xxx@xxx.com
X-Mailer: phpwind电子邮件快递
Content-Transfer-Encoding: base64
Message-Id: <xxx@xxx.com>
Date: Tue,  1 Mar 2011 11:12:54 +0800 (CST)

PGh0bWw+PGhlYWQ+PG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0
L2h0bWw7IGNoYXJzZXQ9Z2IxODAzMCIgLz48dGl0bGU+uNDQu8T616Ky4TwvdGl0bGU+PC9oZWFk
Pjxib2R5PjxkaXYgYWxpZ249ImNlbnRlciI+PHRhYmxlIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3Bh
...


阅读邮件内容,可以看到其中涉及到两个编码方式,一个是第3行的charset=gbk(这个编码格式是指邮件在发送之前使用的编码格式,后来证明这个gbk是不准确的),第二个是第6行的base64(这个是邮件中经常使用的编码格式,邮件在通过Internet传输时所采用的编码格式)。

初步判断是这样:用户写好邮件,邮件系统使用gbk编码格式编码邮件内容,然后采用base64编码格式编码整个信息流,之后通过Internet传输到收件人。

这样对于收件人一方来说,就要通过上面过程的逆过程才能看到邮件原文。即先按base64编码格式解码整个信息流,然后按gbk编码格式解码邮件正文。

根据上面的思路编写代码:

public string Base64ToGBK(string data)
    {
        try
        {
            System.Text.Encoding encoder = Encoding.GetEncoding("GBK");
            System.Text.Decoder gbkDecoder = encoder.GetDecoder();

            // 按base64编码格式解码字符串,得到字节数组
            byte[] toDecodeBytes = Convert.FromBase64String(data);
            // 计算按GBK编码格式,字节数组有多少字符
            int charCount = gbkDecoder.GetCharCount(toDecodeBytes, 0, toDecodeBytes.Length);
            char[] decodedChars = new char[charCount];
            // 使用GBK编码方式对字节数组编码,放到新的字符数组中
            gbkDecoder.GetChars(toDecodeBytes, 0, toDecodeBytes.Length, decodedChars, 0);
            // 将新字符数组组合成字符串
            return new String(decodedChars);
        }
        catch (Exception e)
        {
            throw new Exception("Error in Base64ToGBK" + e.Message);
        }
    }

使用编写的函数对邮件内容进行解码,得到如下结果:

<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb18030" /><title>感谢您注册</title></head><body><div align="center"><table cellpadding="0" cellspa...


我们已经能够看到清晰的邮件内容了。注意解码后的内容里有charset=gb18030,和最开始提到的gbk不一样,两者哪一个更准确有知道的朋友欢迎解释。

即使更换解码方式,即不使用GBK解码,而使用GB18030解码,解码后的结果是相同的。

到此,证明了一开始的判断是正确的。即邮件正文先经过编码(中文一般对应GBK或GB2312编码格式),然后邮件信息流再经过编码(常见的是Base64编码格式),之后通过Internet发送给收件人。

ps:经过解码,发现这个论坛不但将注册用户名发了过来,竟然将密码也一起发了过来!

原文地址:https://www.cnblogs.com/josephchan/p/CSharp_Encoding_Decoding_Email.html