这是我尝试解析的示例原始电子邮件:
MIME-version: 1.0
Content-type: text/html; charset=UTF-8
Content-transfer-encoding: quoted-printable
X-Mailer: Verizon Webmail
X-Originating-IP: [x.x.x.x]
=C2=A0test testing testing 123
Run Code Online (Sandbox Code Playgroud)
什么是= C2 = A0?我尝试过半打引号可解析的解析器,但没有一个正确处理. 如何在C#中正确解析它?
老实说,现在,我正在编码:
//TODO WTF
encoded = encoded.Replace("=C2=A0", "");
Run Code Online (Sandbox Code Playgroud)
因为我无法弄清楚为什么该文本在MIME内容中随机存在,并且不应该被渲染成任何东西.通过删除它,我得到了预期的效果 - 但为什么?!
要清楚,我知道(= [0-9A-F] {2})是一个编码字符.但在这种情况下,它似乎代表什么都没有.
C#中是否存在可以将Quoted-Printable编码转换为String
?的现有类?单击上面的链接以获取有关编码的更多信息.
为方便起见,以上链接引用了以下内容.
任何8位字节的值可以与3个字符,被编码的"="随后两个十六进制数字(0-9或A-F)表示的字节的数值.例如,US-ASCII换页符(十进制值12)可以用"= 0C"表示,US-ASCII等号(十进制值61)用"= 3D"表示.除了可打印的ASCII字符或行尾字符之外的所有字符都必须以这种方式编码.
除"="(十进制61)外,所有可打印的ASCII字符(33到126之间的十进制值)可以由它们自己表示.
ASCII选项卡和空格字符,十进制值9和32,可以由它们自己表示,除非这些字符出现在一行的末尾.如果其中一个字符出现在一行的末尾,则必须将其编码为"= 09"(制表符)或"= 20"(空格).
如果正在编码的数据包含有意义的换行符,则必须将它们编码为ASCII CR LF序列,而不是其原始字节值.相反,如果字节值13和10具有除行尾之外的含义,则它们必须被编码为= 0D和= 0A.
引用可打印编码数据的行不得超过76个字符.为了在不改变编码文本的情况下满足该要求,可以根据需要添加软换行符.软换行符在编码行的末尾包含"=",并且不会在解码的文本中导致换行符.
Python支持一个相当的功能MIME图书馆叫email.mime
.
我想要实现的是获取包含普通UTF-8文本的MIME部分,将其编码为带引号的printables而不是base64.虽然库中提供了所有功能,但我没有设法使用它:
例:
import email.mime.text, email.encoders
m=email.mime.text.MIMEText(u'This is the text containing ünicöde', _charset='utf-8')
m.as_string()
# => Leads to a base64-encoded message, as base64 is the default.
email.encoders.encode_quopri(m)
m.as_string()
# => Leads to a strange message
Run Code Online (Sandbox Code Playgroud)
最后一个命令导致一个奇怪的消息:
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Transfer-Encoding: quoted-printable
GhpcyBpcyB0aGUgdGV4dCBjb250YWluaW5nIMO8bmljw7ZkZQ=3D=3D
Run Code Online (Sandbox Code Playgroud)
这显然不是编码为引用的printables,双头transfer-encoding
最后是奇怪的(如果不是非法).
如何在mime-message中将我的文本编码为带引号的printables?
我正在寻找一种解码quoted-printables的方法.
引用的printables适用于阿拉伯字符,如下所示:
= D8 = B3 = D8 = B9 = D8 = A7 = D8 = AF
我需要将其转换为字符串,并存储或显示..
我已经在stackoverflow上看到了相反的方式(编码),但找不到解码.
一段时间以来,我遇到了一些问题,我的一些用户得到= 0A = 0A而不是我通过PHP发送给他们的电子邮件中的新行.通过电子邮件客户端进行的通信效果很好,但PHP生成的电子邮件总是与某些用户(少数)一样.谷歌搜索没有显示出不错的结果,所有的搜索结果似乎都与某种情况有关 - 并且认为所有Outlook用户都会遇到这个问题是不可接受的.有没有人知道处理这个问题的正确方法并避免这些新的线路编码问题?
编辑:仅供参考我正在使用Zend的Mailer类.
谢谢
编辑2:
更改编码类型不起作用.我将标题编码为base64,将主体编码为64,出现乱码.然后我尝试使用base64头文件,并在主体上执行了base64_decode(base64_decode($ body)),这对于用户的"CNR服务器但不在收件箱中"没什么意义.当我尝试mb_convert_encoding到base64时,我再次得到了编码的字符串而不是正文,所以没用.
我还能尝试什么?Zend Mailer仅支持Quoted Printable和Base64头编码.不知道如何处理它以匹配引用的可打印编码...
此方法将文本编码为QuotedPrintable格式
public static string EncodeQuotedPrintable(string value)
{
if (string.IsNullOrEmpty(value))
return value;
StringBuilder builder = new StringBuilder();
byte[] bytes = Encoding.UTF8.GetBytes(value);
foreach (byte v in bytes)
{
// The following are not required to be encoded:
// - Tab (ASCII 9)
// - Space (ASCII 32)
// - Characters 33 to 126, except for the equal sign (61).
if ((v == 9) || ((v >= 32) && (v <= 60)) || ((v >= 62) && (v <= 126)))
{
builder.Append(Convert.ToChar(v));
} …
Run Code Online (Sandbox Code Playgroud) 我使用 POP3 从 Gmail 帐户下载邮件并将其保存在 SQLite 数据库中以供进一步处理:
mailbox = poplib.POP3_SSL('pop.gmail.com', '995')
mailbox.user(user)
mailbox.pass_(password)
msgnum = mailbox.stat()[0]
for i in range(msgnum):
msg = '\n'.join(mailbox.retr(i+1)[1])
save_message(msg, dbmgr)
mailbox.quit()
Run Code Online (Sandbox Code Playgroud)
但是,在数据库中查找时,除了消息正文(有效负载)的最后一行之外,所有行都有尾随等号。你知道为什么会发生这种情况吗?
在 Python 中,我得到了一个以Quoted-Printable 编码的字符串
mystring="=AC=E9"
Run Code Online (Sandbox Code Playgroud)
此字符串应打印为
é
所以我想解码它并用UTF-8编码,我猜。我明白有些事情是可能的
import quopri
quopri.decodestring('=A3=E9')
Run Code Online (Sandbox Code Playgroud)
但是,我完全迷失了。您将如何解码/编码此字符串以正确打印?
我的Gmail帐号中有以下主题的邮件:
"400,значение,значение"
这是我用来抓邮件的代码:
imap = Net::IMAP.new('imap.gmail.com', 993, true, nil, false)
imap.login(LOGIN, PASSWORD)
imap.select("INBOX")
messages = imap.search(['ALL']).map do |message_id|
msg =imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
result = {:mailbox => msg.from[0].mailbox, :host => msg.from[0].host, :subject => msg.subject, :created_at => msg.date}
imap.store(message_id, "+FLAGS", [:Deleted])
result
end
imap.expunge()
imap.logout
Run Code Online (Sandbox Code Playgroud)
在msg.subject中,我得到以下值"=?KOI8-R?B?MTAwLCDixc7ayc4sIDMwMDAgzMnU0s/X?="
似乎IMAP没有解码它.我应该手动或IMAP库可以为我吗?
我经常收到带有附件的电子邮件,我必须将其提取并保存到磁盘。我基本上执行以下操作(在 Python 2.7 中):
message = email.message_from_file(sys.stdin)
for part in message.walk():
path = email.header.decode_header(part.get_filename())[0][0]
content = part.get_payload(decode=True)
with open(path, 'w') as f:
f.write(content)
Run Code Online (Sandbox Code Playgroud)
这种方法适用于我迄今为止收到的所有类型的附件和所有类型的内容传输编码,除非附件是 ZIP 文件并且Content-Transfer-Encoding
是“引用可打印的”。在这些情况下,写入的 ZIP 文件比原始文件少一个字节(大约整个文件的 60-80%),并unzip
报告如下错误:
% unzip -l foo.zip
Archive: foo.zip
error [foo.zip]: missing 1 bytes in zipfile
(attempting to process anyway)
Length Date Time Name
--------- ---------- ----- ----
440228 01-00-1980 00:00 foo - bar.csv
--------- -------
440228 1 file
Run Code Online (Sandbox Code Playgroud)
和
% unzip foo.zip
Archive: foo.zip
error [foo.zip]: missing …
Run Code Online (Sandbox Code Playgroud)