文字列がbase64かどうかを見分ける方法
質問
さまざまなソースから多数のメールが届きます。 彼らはすべて添付ファイルを持っています、それらの多くは中国語の添付ファイル名を持っているので、これらは 名前はメールクライアントによって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"
2番目の添付ファイル:
------=_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を持っている
解決
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はこれを明示的に拒否しています:
- 「encoded-word」は「quoted-string」内に表示してはなりません。
長い文字列またはUnicode文字が存在する場合にパラメーターヘッダーをエンコードする方法は、 RFC2231 です。これはまったく新しい障害です。ただし、これに対処する標準のメール解析ライブラリを使用する必要があります。
したがって、必要に応じてファイル名パラメータで '=?'
を検出し、RFC2047を介してデコードを試みることができます。ただし、厳密に言うと正しいことは、メーラーの言葉を実際に呼び出し、ファイル =?gb2312?B?uLGxvmhlbrixsb5nLnhscw ==?=
!
他のヒント
ヘッダーの値から次のことがわかります。
=?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のエンコードに注意を払ってください。情報。
@ gnud、@ edg-誤解しない限り、彼はファイルの内容ではなくファイル名について尋ねている @setori-Content-Trasfer-Encodingは、「ファイル名」ではなく、ファイルのコンテンツがどのようにエンコードされるかを示します。
私は専門家ではありませんが、ファイル名のこの部分は後続の文字について彼に伝えています:
=?gb2312?B?
RFCのドキュメントを探しています...ああ!ここにあります: http://tools.ietf.org/html/rfc2047
RFCの説明:
一般に、「エンコードされた単語」は、" =?"で始まり"?="で終わり、間に2つの"?"がある印刷可能なASCII文字のシーケンスです。
他に見るべきものは、バグで使用するMIMEパーサー(C#)であるSharpMimeToolsのコードです。追跡アプリ、 BugTracker.NET
decode_header
の出力を処理するには、bobinceのメソッドよりも良い方法があります。ここで見つけました: http://mail.python.org /pipermail/email-sig/2007-March/000332.html
name = unicode(email.header.make_header(email.header.decode_header(x)))
さて、メールヘッダーを辞書に解析します。そして、Content-Transfer-Encodingが設定されているかどうか、およびそれが" base64"であるかどうかを確認します。または" base-64"。
質問:"""また、実際には.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文字です。