Question

J'ai de nombreux courriels provenant de différentes sources. ils ont tous des pièces jointes, beaucoup d'entre eux ont des noms d'attachement en chinois, donc ceux-ci les noms sont convertis en base64 par leurs clients de messagerie.

Lorsque je reçois ces courriels, je souhaite décoder le nom. mais il y a d'autres noms qui sont pas base64. Comment différencier une chaîne de base64 en utilisant le langage de programmation jython ?

Ie.

Première pièce jointe:

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

deuxième pièce jointe:

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

Veuillez noter les deux " codage de transfert de contenu ". avoir base64

Était-ce utile?

La solution

  

Veuillez noter que les codage de transfert de contenu ont une base64

Non pertinent dans ce cas, le Content-Transfer-Encoding s'applique uniquement à la charge utile du corps, pas aux en-têtes.

=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=

Il s'agit d'un atome d'en-tête codé par RFC2047 . La fonction stdlib à décoder est email.header.decode_header . Il faut encore un peu de post-traitement pour interpréter le résultat de cette fonction:

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

Cependant ...

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

C'est tout simplement faux. Quel mailer l'a créé? Le codage RFC2047 ne peut se produire que dans des atomes et une chaîne entre guillemets n'est pas un atome. RFC2047 & # 167; 5 le nie explicitement:

  
      
  • Un 'mot codé' NE DOIT PAS apparaître dans une 'chaîne de caractères'.
  •   

Le moyen accepté de coder les en-têtes de paramètres en cas de présence de longues chaînes ou de caractères Unicode est RFC2231 , ce qui est un tout nouveau sac de blessures. Cependant, vous devriez utiliser une bibliothèque d’analyse de courrier standard qui saura vous aider.

Vous pouvez donc détecter le '=?' dans les paramètres de nom de fichier si vous le souhaitez et essayer de le décoder via RFC2047. Cependant, la chose correcte à faire correctement est de prendre le courrier à son mot et d’appeler réellement le fichier =? Gb2312? B? ULGxvmhlbrixsb5nLnhscw ==? = !

Autres conseils

La valeur de l'en-tête vous indique ceci:

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

Donc, fractionner sur "?" vous obtient réellement ceci (notation JSON)

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

Dans le tableau résultant, si " B " est en position 2, vous faites face à une chaîne encodée en base 64 en position 3. Une fois que vous l'avez décodé, veillez à faire attention au codage en position 1, il serait probablement préférable de convertir le tout en UTF-8 en utilisant celui-ci. info.

@gnud, @edg - À moins que je ne comprenne mal, il pose des questions sur le nom du fichier, pas sur le contenu du fichier. @setori - le Content-Trasfer-Encoding vous indique comment le CONTENU du fichier est codé, et non le "nom de fichier".

Je ne suis pas un expert, mais cette partie du nom de fichier l'informe des caractères suivants:

=? gb2312? B?

Je cherche la documentation dans les RFC ... Ah! le voici: http://tools.ietf.org/html/rfc2047

La RFC dit:

En général, un "mot codé" est une séquence de caractères ASCII imprimables qui commence par "=", se termine par "? =" et comporte deux "?" entre les deux.

Le code dans SharpMimeTools, un analyseur MIME (en C #) que j’utilise dans mon bug, doit également être examiné. suivi de l'application, BugTracker.NET

Il existe un meilleur moyen que la méthode de bobince pour gérer la sortie de decode_header . Je l'ai trouvé ici: http://mail.python.org /pipermail/email-sig/2007-March/000332.html

name = unicode(email.header.make_header(email.header.decode_header(x)))

Eh bien, vous analysez l'en-tête de l'e-mail dans un dictionnaire. Et ensuite, vous vérifiez si Content-Transfer-Encoding est défini et s'il = " base64 " ou "base 64".

Question: " " De plus, j’ai besoin de savoir de quel type de fichier il s’agit, c’est-à-dire .xls ou .doc, donc j’ai besoin de décoder le nom du fichier pour pouvoir traiter correctement la pièce jointe, mais comme ci-dessus, cela semble gb2312 n’est pas pris en charge dans Jython, connaissez-vous des ronds-points? "" "

Données:

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

Observations:

(1) La première ligne indique Microsoft Excel. .xls est donc meilleur que .doc

.

(2)

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

(a) L'extension semble être .xls - aucun codec gb2312 n'est nécessaire -
(b) Si vous souhaitez un nom de fichier sécurisé pour le système de fichiers, vous pouvez utiliser le code " -_ " variante de base64 OU vous pourriez le coder en pourcentage

(c) Pour ce que ça vaut, le nom du fichier est XYhenXYg.xls où X et Y sont 2 caractères chinois qui ensemble signifient "copier". et le reste sont des caractères ASCII littéraux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top