如何判断字符串是否是base64

发布于 2024-07-09 02:10:25 字数 799 浏览 6 评论 0原文

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

I have many emails coming in from different sources.
they all have attachments, many of them have attachment names in chinese, so these
names are converted to base64 by their email clients.

When I receive these emails, I wish to decode the name. but there are other names which are
not base64. How can I differentiate whether a string is base64 or not, using the jython programming language?

Ie.

First attachment:

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

second attachment:

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

Please note both "Content-Transfer-Encoding" have base64

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

|煩躁 2024-07-16 02:10:25

标头值告诉您这一点:

=?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 上看到一个 Base-64 编码的字符串。解码后,请务必注意位置 1 上的编码,可能最好使用该信息将整个内容转换为 UTF-8。

The header value tells you this:

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

So splitting on "?" actually gets you this (JSON notation)

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

In the resulting array, if "B" is on position 2, you face a base-64 encoded string on position 3. Once you decoded it, be sure to pay attention to the encoding on position 1, probably it would be best to convert the whole thing to UTF-8 using that info.

ぽ尐不点ル 2024-07-16 02:10:25

请注意 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==?=

Please note both Content-Transfer-Encoding have base64

Not relevant in this case, the Content-Transfer-Encoding only applies to the body payload, not to the headers.

=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=

That's an RFC2047-encoded header atom. The stdlib function to decode it is email.header.decode_header. It still needs a little post-processing to interpret the outcome of that function though:

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

However...

Content-Type: application/vnd.ms-excel;
 name="=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?="

This is simply wrong. What mailer created it? RFC2047 encoding can only happen in atoms, and a quoted-string is not an atom. RFC2047 §5 explicitly denies this:

  • An 'encoded-word' MUST NOT appear within a 'quoted-string'.

The accepted way to encode parameter headers when long string or Unicode characters are present is RFC2231, which is a whole new bag of hurt. But you should be using a standard mail-parsing library which will cope with that for you.

So, you could detect the '=?' in filename parameters if you want, and try to decode it via RFC2047. However, the strictly-speaking-correct thing to do is to take the mailer at its word and really call the file =?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=!

海的爱人是光 2024-07-16 02:10:25

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

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

=?gb2312?B?

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

RFC 说:

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

另外值得一看的是 SharpMimeTools 中的代码,它是我在 错误跟踪应用程序,BugTracker.NET

@gnud, @edg - Unless I misunderstand, he's asking about the filename, not the file content
@setori - the Content-Trasfer-Encoding is telling you how the CONTENT of the file is encoded, not the "filename".

I'm not an expert, but this part here in the filename is telling him about the characters that follow:

=?gb2312?B?

I'm looking for the documentation in the RFCs... Ah! here it is: https://www.rfc-editor.org/rfc/rfc2047

The RFC says:

Generally, an "encoded-word" is a sequence of printable ASCII characters that begins with "=?", ends with "?=", and has two "?"s in between.

Something else to look at is the code in SharpMimeTools, a MIME parser (in C#) that I use in my bug tracking app, BugTracker.NET

野侃 2024-07-16 02:10:25

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

There is a better way than bobince’s method to handle the output of decode_header. I found it here: http://mail.python.org/pipermail/email-sig/2007-March/000332.html

name = unicode(email.header.make_header(email.header.decode_header(x)))
黑白记忆 2024-07-16 02:10:25

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

Well, you parse the email header into a dictionary. And then you check if Content-Transfer-Encoding is set, and if it = "base64" or "base-64".

爱她像谁 2024-07-16 02:10:25

问题:“”“而且我实际上需要知道它是什么类型的文件,即 .xls 或 .doc,因此我确实需要解码文件名以便正确处理附件,但如上所述,jython 似乎不支持 gb2312 ,知道任何回旋处吗?"""

数据:

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

Question: """Also I actually need to know what type of file it is ie .xls or .doc so I do need to decode the filename in order to correctly process the attachment, but as above, seems gb2312 is not supported in jython, know any roundabouts?"""

Data:

Content-Type: application/vnd.ms-excel;
 name="=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?="

Observations:

(1) The first line indicates Microsoft Excel, so .xls is looking better than .doc

(2)

>>> import base64
>>> base64.b64decode("uLGxvmhlbrixsb5nLnhscw==")
'\xb8\xb1\xb1\xbehen\xb8\xb1\xb1\xbeg.xls'
>>>

(a) The extension appears to be .xls -- no need for a gb2312 codec
(b) If you want a file-system-safe file name, you could use the "-_" variant of base64 OR you could percent-encode it
(c) For what it's worth, the file name is XYhenXYg.xls where X and Y are 2 Chinese characters that together mean "copy" and the remainder are literal ASCII characters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文