如何判断字符串是否为base64

时间:2008-11-07 09:54:35

标签: python jython base64 mime

我收到了很多来自不同来源的电子邮件。 他们都有附件,其中很多都有中文附件名,所以这些 名称由其电子邮件客户端转换为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

6 个答案:

答案 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字符。