Pergunta

Eu tenho muitos e-mails provenientes de diferentes fontes. todos eles têm anexos, muitos deles têm nomes de anexos em chinês, assim que estes nomes são convertidos para base64 por seus clientes de e-mail.

Quando eu receber esses e-mails, eu desejo para decodificar o nome. mas há outros nomes que são não base64. Como posso diferenciar se uma string é base64 ou não, usando o Jython linguagem de programação ?

Ie.

Primeiro anexo:

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

segundo anexo:

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

Por favor, note tanto " Content-Transfer-Encoding " Have base64

Foi útil?

Solução

Por favor, note tanto Content-Transfer-Encoding Tem base64

Não é relevante neste caso, o Content-Transfer-Encoding só se aplica à carga corpo, para não os cabeçalhos.

=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=

Isso é um RFC2047 codificado pelo cabeçalho átomo. A função stdlib para descodificar é email.header.decode_header. Ele ainda precisa de um pouco de pós-processamento para interpretar o resultado dessa função no entanto:

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

No entanto ...

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

Isto é simplesmente errado. O mailer criou? codificação RFC2047 só pode acontecer em átomos, e uma cadeia de caracteres citado não é um átomo de. RFC2047 §5 nega explicitamente o seguinte:

  • Uma 'palavra-codificado', não deve aparecer dentro de um 'citou-corda'.

A maneira aceitável de cabeçalhos de parâmetro codificar quando cadeia longa ou caracteres Unicode estão presentes é RFC2231 , que é um saco totalmente novo de dor. Mas você deve estar usando uma biblioteca de análise de e-mail padrão que irá lidar com isso para você.

Então, você poderia detectar a '=?' nos parâmetros de nome de arquivo, se quiser, e tentar decodificá-lo via RFC2047. No entanto, a coisa estritamente falando-correta de fazer é levar o mailer em sua palavra e realmente chamar a =?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?= arquivo!

Outras dicas

O valor do cabeçalho diz-lhe isto:

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

Assim, a divisão em "?" na verdade, você recebe este (notação JSON)

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

Na matriz resultante, se "B" está na posição 2, você enfrenta uma base 64 string codificada na posição 3. Uma vez que você decodificado-lo, certifique-se de prestar atenção a codificação na posição 1, provavelmente seria melhor para converter a coisa toda para UTF-8 usando essa informação.

@gnud, @edg - A menos que eu entenda mal, ele está perguntando sobre o nome do arquivo, não o conteúdo do arquivo @setori -. o Content-trasfer-Encoding está lhe dizendo como o conteúdo do arquivo é codificado, e não o "nome do arquivo"

Eu não sou um especialista, mas esta parte aqui no nome do arquivo é dizendo-lhe sobre os personagens que se seguem:

=? GB2312? B?

Eu estou procurando a documentação nas RFCs ... Ah! aqui está: http://tools.ietf.org/html/rfc2047

O RFC diz:

Geralmente, uma "palavra-codificado" é uma seqüência de caracteres ASCII imprimíveis que começa com "=?", Termina com "? =", E tem dois "?" S no meio.

Outra coisa é olhar para o código no SharpMimeTools, um analisador MIME (em C #) que eu uso na minha bug rastreamento aplicativo, BugTracker.NET

Há uma maneira melhor do que o método de bobince para lidar com a saída do decode_header. Eu encontrei-o aqui: http://mail.python.org /pipermail/email-sig/2007-March/000332.html

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

Bem, você analisar o cabeçalho de e-mail em um dicionário. E então você verificar se Content-Transfer-Encoding é conjunto, e se ele = "base64" ou "base64".

Pergunta: "" "Também eu realmente preciso saber que tipo de arquivo é ie .xls ou .doc então eu faço necessidade de decodificar o nome do arquivo, a fim de processar corretamente o anexo, mas como acima, parece gb2312 não é suportado em jython, conhece algum rotundas? "" "

Data:

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

Observações:

(1) A primeira linha indica Microsoft Excel, de modo .xls está olhando melhor do que .doc

(2)

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

(a) A extensão parece ser .xls - sem necessidade de um gb2312 codec
(B) Se você quer um nome de arquivo file-system-safe, você poderia usar o "-_" variante de base64 ou você poderia por cento codificar-lo
(C) Por que vale a pena, o nome do arquivo é XYhenXYg.xls onde X e Y são 2 caracteres chineses que, juntos média "cópia" e os restantes são caracteres ASCII literal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top