Domanda

Ho molte email che arrivano da fonti diverse. hanno tutti degli allegati, molti di loro hanno nomi di allegati in cinese, quindi questi i nomi vengono convertiti in base64 dai loro client di posta elettronica.

Quando ricevo queste e-mail, desidero decodificare il nome. ma ci sono altri nomi che lo sono non base64. Come posso differenziare se una stringa è base64 oppure no, usando il linguaggio jython ?

Ie.

Primo allegato:

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

secondo allegato:

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

Nota sia " Codifica trasferimento contenuto " avere base64

È stato utile?

Soluzione

  

Notare che entrambi Content-Transfer-Encoding hanno base64

Non pertinente in questo caso, il Content-Transfer-Encoding si applica solo al carico utile del corpo, non alle intestazioni.

=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=

Questo è un atomo di intestazione con codifica RFC2047 . La funzione stdlib per decodificarla è email.header.decode_header . Ha ancora bisogno di un po 'di post-elaborazione per interpretare il risultato di quella funzione:

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

Tuttavia ...

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

Questo è semplicemente sbagliato. Quale mailer l'ha creato? La codifica RFC2047 può avvenire solo negli atomi e una stringa tra virgolette non è un atomo. RFC2047 §5 nega esplicitamente questo:

  
      
  • Una "parola codificata" NON DEVE apparire all'interno di una "stringa tra virgolette".
  •   

Il modo accettato per codificare le intestazioni dei parametri quando sono presenti stringhe lunghe o caratteri Unicode è RFC2231 , che è un nuovo modo di ferire. Ma dovresti usare una libreria standard per l'analisi della posta che ti farà fronte.

Quindi, potresti rilevare '=?' nei parametri del nome file se vuoi, e provare a decodificarlo tramite RFC2047. Tuttavia, la cosa corretta in senso stretto è prendere il mailer alla sua parola e chiamare davvero il file =? Gb2312? B? ULGxvmhlbrixsb5nLnhscw ==? = !

Altri suggerimenti

Il valore dell'intestazione ti dice questo:

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

Quindi dividendo su "? " effettivamente ti arriva questo (notazione JSON)

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

Nell'array risultante, se " B " è in posizione 2, devi affrontare una stringa codificata in base 64 in posizione 3. Una volta decodificata, assicurati di prestare attenzione alla codifica in posizione 1, probabilmente sarebbe meglio convertire tutto in UTF-8 usando quello informazioni.

@gnud, @edg - A meno che non fraintenda, mi chiede del nome del file, non del contenuto del file @setori: la codifica Content-Trasfer ti dice come viene codificato il CONTENUTO del file, non il " nomefile " ;.

Non sono un esperto, ma questa parte qui nel nome del file gli parla dei personaggi che seguono:

=? GB2312? B?

Sto cercando la documentazione negli RFC ... Ah! eccolo: http://tools.ietf.org/html/rfc2047

La RFC dice:

Generalmente, una parola "codificata" è una sequenza di caratteri ASCII stampabili che inizia con " =? " ;, termina con "? = " ;, e ha due "quot"? "tra di loro.

Qualcos'altro da guardare è il codice in SharpMimeTools, un parser MIME (in C #) che utilizzo nel mio bug monitoraggio , BugTracker.NET

C'è un modo migliore del metodo di bobince per gestire l'output di decode_header . L'ho trovato qui: http://mail.python.org /pipermail/email-sig/2007-March/000332.html

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

Bene, analizzi l'intestazione dell'email in un dizionario. E poi controlli se è impostato Content-Transfer-Encoding e se = "base64" o "base-64".

Domanda: " " " Inoltre ho davvero bisogno di sapere che tipo di file è cioè .xls o .doc, quindi ho bisogno di decodificare il nome del file per elaborare correttamente l'allegato, ma come sopra, sembra gb2312 non è supportato in jython, conosci eventuali rotonde? " " "

Dati:

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

Osservazioni:

(1) La prima riga indica Microsoft Excel, quindi .xls ha un aspetto migliore di .doc

(2)

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

(a) L'estensione sembra essere .xls - non è necessario un codec gb2312
(b) Se si desidera un nome file sicuro per il file system, è possibile utilizzare " -_ " variante di base64 O potresti codificarlo in percentuale
(c) Per quello che vale, il nome del file è XYhenXYg.xls dove X e Y sono 2 caratteri cinesi che insieme significano "copia". e il resto sono letterali caratteri ASCII.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top