1

У меня есть файл электронной почты .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="" кажется, закодировано GBK, но .decode Python .decode('gbk') на нем не работает, возвращается та же строка:

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

Итак, в чем заключается эта строка и как ее декодировать?

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

1 ответ1

3

Эти -

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

- MIME Encoded-Words. Общая форма:

=?charset?encoding?encoded text?=

Вы правы, что кодировка - это GBK, но вы должны сначала интерпретировать транспортную кодировку, которая либо B для Base64, либо Q для Quoted-Printable. Таким образом:

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

Однако, email.header справится с этим лучше:

py3.5 >>> email.header.decode_header("=?GBK?B?1cK5scf4s8e53L7WudjT2s34wufT38fp0MXPoteo?= =?GBK?B?sai1xLTwuLQoz8K6vszBMbrFKS5kb2M=?=")
[(b'\xd5\xc2\xb9\xb1\xc7\xf8\xb3\xc7\xb9\xdc\xbe\xd6\xb9\xd8\xd3\xda\xcd\xf8\xc2\xe7\xd3\xdf\xc7\xe9\xd0\xc5\xcf\xa2\xd7\xa8\xb1\xa8\xb5\xc4\xb4\xf0\xb8\xb4(\xcf\xc2\xba\xbe\xcc\xc11\xba\xc5).doc', 'gbk')]
py3.5 >>> _[0][0].decode(_[0][1])
'章贡区城管局关于网络舆情信息专报的答复(下壕塘1号).doc'

Структура первого результата такова, что один заголовок может иметь несколько компонентов, то есть разные кодировки или смешанный необработанный текст и Encoded-Words. В отличие от Perl Encode, модуль Python оставляет за вами право присоединиться () к результатам:

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:

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

(Кроме того, тело не закодировано, оно закодировано в Base64 . Они используют разные наборы символов, хотя оба имеют кодировку 3:4, а uudecode обычно достаточно умен, чтобы обнаружить необработанный Base64.)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .