我收到了很多来自不同来源的电子邮件。 他们都有附件,其中很多都有中文附件名,所以这些 名称由其电子邮件客户端转换为base64。
当我收到这些电子邮件时,我想解码这个名字。但还有其他名字 不是base64。如何使用 jython 编程语言来区分字符串是否为base64?
IE中。
第一个附件:
------=_NextPart_000_0091_01C940CC.EF5AC860
Content-Type: application/vnd.ms-excel;
name="Copy of Book1.xls"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="Copy of Book1.xls"
第二个附件:
------=_NextPart_000_0091_01C940CC.EF5AC860
Content-Type: application/vnd.ms-excel;
name="=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?="
请注意“ Content-Transfer-Encoding ”都有base64
答案 0 :(得分:21)
标题值告诉您:
=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?= "=?" introduces an encoded value "gb2312" denotes the character encoding of the original value "B" denotes that B-encoding (equal to Base64) was used (the alternative is "Q", which refers to something close to quoted-printable) "?" functions as a separator "uLG..." is the actual value, encoded using the encoding specified before "?=" ends the encoded value
分裂“?”实际上得到你(JSON表示法)
["=", "gb2312", "B", "uLGxvmhlbrixsb5nLnhscw==", "="]
在结果数组中,如果“B”在位置2上,则在第3位面对基数为64的编码字符串。解码后,请务必注意位置1上的编码,可能是最好使用该信息将整个事物转换为UTF-8。
答案 1 :(得分:12)
请注意
Content-Transfer-Encoding
都有base64
在这种情况下不相关,Content-Transfer-Encoding
仅适用于正文有效负载,而不适用于标题。
=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=
这是 RFC2047 - 编码的标头原子。解码它的stdlib函数是email.header.decode_header
。它仍然需要一些后处理来解释该函数的结果:
import email.header
x= '=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?='
try:
name= u''.join([
unicode(b, e or 'ascii') for b, e in email.header.decode_header(x)
])
except email.Errors.HeaderParseError:
pass # leave name as it was
...然而
Content-Type: application/vnd.ms-excel;
name="=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?="
这是完全错误的。邮件是什么创建的? RFC2047编码只能在原子中发生,而引用的字符串不是原子。 RFC2047§5明确否认:
- “编码字”绝不能出现在“引用字符串”中。
当存在长字符串或Unicode字符时,接受的编码参数标头的方法是 RFC2231 ,这是一个全新的伤害包。但是你应该使用一个标准的邮件解析库来处理这个问题。
因此,您可以根据需要检测文件名参数中的'=?'
,并尝试通过RFC2047对其进行解码。但是,严格说来正确的事情就是把邮件发送到它的话,然后真正调用文件=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=
!
答案 2 :(得分:7)
@gnud,@ edg - 除非我误解,否则他会询问文件名,而不是文件内容 @setori - Content-Trasfer-Encoding告诉你如何编码文件的内容,而不是“文件名”。
我不是专家,但文件名中的这一部分告诉他下面的字符:
=?GB2312 2 B 4
我正在寻找RFC中的文档......啊!这是:http://tools.ietf.org/html/rfc2047
RFC说:
通常,“编码字”是一系列可打印的ASCII字符,以“=?”开头,以“?=”结尾,中间有两个“?”。 / em>
要查看的其他内容是SharpMimeTools中的代码,我在bug tracking应用中使用的MIME解析器(在C#中),BugTracker.NET
答案 3 :(得分:2)
有一种比bobince方法更好的方法来处理decode_header
的输出。我在这里找到了它:http://mail.python.org/pipermail/email-sig/2007-March/000332.html
name = unicode(email.header.make_header(email.header.decode_header(x)))
答案 4 :(得分:0)
好吧,您将电子邮件标题解析为字典。然后检查是否设置了Content-Transfer-Encoding,如果它=“base64”或“base-64”。
答案 5 :(得分:0)
问题:“”“另外我实际上需要知道它是什么类型的文件,即.xls或.doc所以我需要解码文件名以便正确处理附件,但如上所述,似乎gb2312不是在jython中支持,知道任何环形交叉口吗?“”“
数据:
Content-Type: application/vnd.ms-excel;
name="=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?="
观察:
(1)第一行表示Microsoft Excel,因此.xls
看起来好于.doc
(2)
>>> import base64
>>> base64.b64decode("uLGxvmhlbrixsb5nLnhscw==")
'\xb8\xb1\xb1\xbehen\xb8\xb1\xb1\xbeg.xls'
>>>
(a)扩展程序似乎是.xls
- 不需要gb2312
编解码器
(b)如果你想要一个文件系统安全的文件名,你可以使用base64的“-_”变体,或者你可以对它进行百分比编码
(c)对于它的价值,文件名是XYhenXYg.xls
,其中X和Y是2个汉字,一起表示“复制”,其余部分是文字ASCII字符。