这个看似GBK编码的字符串该如何解码呢?

这个看似GBK编码的字符串该如何解码呢?

我有一个.eml包含 MS-Word 附件的电子邮件文件:

------=_Part_239376_662463351.1415605722579
Content-Type: application/msword;
 name="=?GBK?B?1cK5scf4s8e53L7WudjT2s34wufT38fp0MXPoteo?=
 =?GBK?B?sai1xLTwuLQoz8K6vszBMbrFKS5kb2M=?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="=?GBK?B?1cK5scf4s8e53L7WudjT2s34wufT38fp0MXPoteo?=
 =?GBK?B?sai1xLTwuLQoz8K6vszBMbrFKS5kb2M=?="

0M8R4KGxGuEAAAAAAAAA [rest of base64-encoded attachment]

我成功对附件进行了 base64 解码,文件内容正常。
但是如何解码文件名呢?

的价值filename="" 似乎成为繁體中文-encoded 但 Python.decode('gbk')无法运作,返回相同的字符串:

>>> "1cK5scf4s8e53L7WudjT2s34wufT38fp0MXPoteo".decode('gbk')
u'1cK5scf4s8e53L7WudjT2s34wufT38fp0MXPoteo'

那么,这个字符串是用什么编码的以及如何解码呢?

=?GBK?B?1cK5scf4s8e53L7WudjT2s34wufT38fp0MXPoteo?=
=?GBK?B?sai1xLTwuLQoz8K6vszBMbrFKS5kb2M=?=

答案1

这些 -

=?GBK?B?1cK5scf4s8e53L7WudjT2s34wufT38fp0MXPoteo?=
=?GBK?B?sai1xLTwuLQoz8K6vszBMbrFKS5kb2M=?=

– 是 MIME编码词.一般形式为:

=?<字符集>?<传输编码>?<编码文本>?=

你说的没错,字符集是 GBK,但你必须先解开传输编码,用于BBase64 或QQuoted-Printable,以获取实际的 GBK 编码字节:

>>> base64.b64decode("sai1xLTwuLQoz8K6vszBMbrFKS5kb2M=").decode("GBK")
'报的答复(下壕塘1号).doc'

然而,email.header.decode_header()可以更好地处理这个问题:

>>> x = email.header.decode_header("=?GBK?B?1cK5s<...>brFKS5kb2M=?=")
>>> x
[(b'\xd5\xc2\xb9\xb1<...>\xc11\xba\xc5).doc', 'gbk')]
>>> x[0][0].decode(x[0][1])
'章贡区城管局关于网络舆情信息专报的答复(下壕塘1号).doc'

第一个结果的结构是这样的,因为单个标题可能有多个组件,即不同的编码或混合的原始文本和编码词。Python 模块让您自行 join() 结果:

def decode_header(enc):
    dec = email.header.decode_header(enc)
    dec = [f[0].decode(f[1] or "us-ascii") for f in dec]
    return "".join(dec)

类似地,在 Perl 中,它Encode::decode()也可以使用MIME-Header编码来处理这个问题:

$ perl -E 'use open qw(:std :utf8);
           use Encode;
           say Encode::decode("MIME-Header", "=?GBK?B?1cK5scf<...>brFKS5kb2M=?=");'
章贡区城管局关于网络舆情信息专报的答复(下壕塘1号).doc

(另外,主体不是 uuencoded 的,而是Base64-编码。它们使用不同的字符集,尽管两者都是 3:4 编码,并且uudecode通常足够智能,可以检测原始 Base64。)

相关内容