【问题标题】:how to tell if a string is base64 or not如何判断字符串是否为base64
【发布时间】:2010-09-21 06:17:39
【问题描述】:

我收到了许多来自不同来源的电子邮件。 都有附件,很多都有中文的附件名,所以这些 名称由其电子邮件客户端转换为 base64。

当我收到这些电子邮件时,我希望解码名称。但还有其他名称 不是base64。如何使用 jython 编程语言区分字符串是否为 base64?

即。

第一个附件:

------=_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

【问题讨论】:

    标签: python jython base64 mime


    【解决方案1】:

    标题值告诉你:

    =?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?= “=?”引入一个编码值 “gb2312”表示原始值的字符编码 “B”表示使用了 B 编码(等于 Base64)(替代 是“Q”,它指的是接近引用可打印的东西) “?”用作分隔符 "uLG..." 是实际值,使用之前指定的编码进行编码 "?=" 结束编码值

    所以拆分“?”实际上得到了这个(JSON 表示法)

    ["=", "gb2312", "B", "uLGxvmhlbrixsb5nLnhscw==", "="]

    在结果数组中,如果“B”在位置 2,那么你在位置 3 上会遇到一个 base-64 编码的字符串。解码后,一定要注意位置 1 上的编码,可能是最好使用该信息将整个内容转换为 UTF-8。

    【讨论】:

    • 不错,从0开始计数
    • 这个答案是否基于权威文档?
    • 太好了,感谢您对 Tomalak 的明确回答!在你和 bobince 之间很难决定谁得到正确的答案,你对编码的本质有了清晰的理解。但我会尝试 email.header.decode_header 的东西,它只是为我做的!不过,我仍然支持你!
    【解决方案2】:

    请注意Content-Transfer-Encoding 都有base64

    在这种情况下不相关,Content-Transfer-Encoding 仅适用于正文有效负载,不适用于标头。

    =?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=
    

    这是一个 RFC2047 编码的标头原子。解码它的标准库函数是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==?=

    【讨论】:

    • 我尝试通过 '=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=' 调用附件,但不幸的是它只是崩溃并痛苦地抱怨,我不知道为什么,也许正在调查那个抱怨会更快地解决问题,感谢 bobince 欣赏它
    • 什么时候抱怨什么?如果您尝试实际保存具有该名称的文件,操作系统可能会感到不安,当然,但是任何时候您从用户输入中获取文件名时,您都需要一些非常严格的过滤来阻止危险字符 - 最好只允许 [a -zA-Z0-9_] (也捕获一个空字符串)。
    • & 如果 Outlook 创建了这个,我会感到惊讶,即使按照 Microsoft 标准,它也是非常畸形的! :-)
    • +1 用于 python 实现和所有附加信息。干杯!
    • 另外我实际上需要知道它是什么类型的文件,即 .xls 或 .doc 所以我确实需要解码文件名才能正确处理附件,但如上所述,似乎 gb2312 不是在 jython 中支持,知道任何环形交叉路口吗?
    【解决方案3】:

    @gnud, @edg - 除非我理解错了,否则他问的是文件名,而不是文件内容 @setori - Content-Trasfer-Encoding 告诉你文件的内容是如何编码的,而不是“文件名”。

    我不是专家,但文件名中的这一部分告诉他后面的字符:

    =?gb2312?B?

    我正在寻找 RFC 中的文档...啊!这里是:https://www.rfc-editor.org/rfc/rfc2047

    RFC 说:

    通常,“编码字”是一系列可打印的 ASCII 字符,以“=?”开头,以“?=”结尾,中间有两个“?”。

    要查看的其他内容是 SharpMimeTools 中的代码,这是我在 bug tracking 应用程序 BugTracker.NET 中使用的 MIME 解析器(C# 中)

    【讨论】:

    • 正确我在询问文件名而不是内容,我从来没有遇到过问题,即使它有中文字符。因为都是base64
    【解决方案4】:

    有比 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)))
    

    【讨论】:

      【解决方案5】:

      好吧,您将电子邮件标题解析为字典。然后检查是否设置了 Content-Transfer-Encoding,以及它是否 = "base64" 或 "base-64"。

      【讨论】:

        【解决方案6】:

        问题:“”“另外我实际上需要知道它是什么类型的文件,即 .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 字符。

        【讨论】:

          猜你喜欢
          • 2014-11-20
          • 1970-01-01
          • 2011-05-31
          • 2010-11-21
          • 1970-01-01
          • 2020-08-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多