web-dev-qa-db-ja.com

この一見GBKでエンコードされた文字列をデコードする方法は?

MS-Wordの添付ファイルを含む_.eml_電子メールファイルがあります。

_------=_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=""_ seemsの値は [〜#〜] gbk [〜#〜] -エンコードされていますが、Pythonの.decode('gbk')は機能しませんその上で、同じ文字列が返されました:

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

では、この文字列は何にエンコードされ、どのようにデコードするのでしょうか?

_=?GBK?B?1cK5scf4s8e53L7WudjT2s34wufT38fp0MXPoteo?=
=?GBK?B?sai1xLTwuLQoz8K6vszBMbrFKS5kb2M=?=
_
1
Nicolas Raoul

これら–

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

–はMIMEエンコードされたワードです。一般的な形式は次のとおりです。

=?文字コードエンコーディングエンコードされたテキスト?=

文字セットがGBKであることは正しいですが、最初にトランスポートエンコーディングを解釈する必要があります。これはBase64の場合はB、の場合はQです。引用-印刷可能。したがって:

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'

最初の結果の構造は、単一のヘッダーに複数のコンポーネントが含まれる可能性があるためです。つまり、異なるエンコーディング、または生のテキストとエンコードされたワードの混合です。 Perlのエンコードとは異なり、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と言えば:

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

(また、本文はuuencodeされておらず、Base64-エンコードされています。どちらも3:4エンコードであり、uudecodeは通常、生のBase64を検出するのに十分賢いです。)

5
user1686