2008-11-07 37 views
6

Tôi có nhiều email đến từ các nguồn khác nhau. tất cả đều có tệp đính kèm, nhiều người trong số họ có tên tệp đính kèm bằng tiếng Trung, vì vậy các tên này được chuyển đổi thành base64 bởi ứng dụng email của họ.cách để biết chuỗi có phải là base64 hay không

Khi tôi nhận được những email này, tôi muốn giải mã tên. nhưng có những tên khác là không phải base64. Làm cách nào tôi có thể phân biệt chuỗi có phải là base64 hay không, sử dụng ngôn ngữ lập trình jython?

Tức là.

tập tin đính kèm Đầu tiên:

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

thứ hai tập tin đính kèm:

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

Xin lưu ý cả "Content-Transfer-Encoding" có base64

Trả lời

12

Xin lưu ý cả Content-Transfer-Encoding có base64

Không có liên quan trong trường hợp này, Content-Transfer-Encoding chỉ áp dụng cho các tải trọng cơ thể, chứ không phải để các tiêu đề.

=?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?= 

Đó là một RFC2047 nguyên tử đầu -encoded. Hàm stdlib để giải mã nó là email.header.decode_header. Nó vẫn cần một chút sau xử lý để giải thích kết quả của hàm mặc dù:

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 

Tuy nhiên ...

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

này chỉ đơn giản là sai. Người tạo thư gì? Mã hóa RFC2047 chỉ có thể xảy ra trong các nguyên tử, và một chuỗi trích dẫn không phải là một nguyên tử. RFC2047 §5 phủ nhận một cách rõ ràng này:

  • Một 'mã hóa-word' PHẢI KHÔNG xuất hiện trong vòng một 'quoted-string'.

Cách chấp nhận để mã hóa tiêu đề tham số khi chuỗi dài hoặc các ký tự Unicode có mặt là RFC2231, mà là một chiếc túi hoàn toàn mới của tổn thương. Nhưng bạn nên sử dụng thư viện phân tích cú pháp thư chuẩn để đối phó với điều đó cho bạn.

Vì vậy, bạn có thể phát hiện các thông số '=?' trong tên tệp nếu muốn và cố gắng giải mã thông qua RFC2047. Tuy nhiên, điều đúng đắn phải làm là lấy bưu phẩm tại từ của nó và thực sự gọi đến tập tin =?gb2312?B?uLGxvmhlbrixsb5nLnhscw==?=!

+0

Tôi sẽ đoán triển vọng tạo ra nó .... không chắc chắn – Setori

+0

Tôi đã thử chỉ cần gọi tập tin đính kèm chỉ bằng '=? Gb2312? B? ULGxvmhlbrixsb5nLnhscw ==? =' Nhưng không may nó chỉ sụp đổ và phàn nàn cay đắng, tôi không biết tại sao , có thể nhìn vào khiếu nại đó sẽ giải quyết vấn đề nhanh hơn, nhờ bobince đánh giá cao nó – Setori

+0

Điều gì phàn nàn và khi nào? Hệ điều hành có thể sẽ khó chịu nếu bạn thực sự lưu một tệp với tên đó, chắc chắn, nhưng bất cứ khi nào bạn lấy tên tệp từ đầu vào của người dùng, bạn sẽ cần một số bộ lọc rất nghiêm ngặt để giữ các ký tự nguy hiểm - tốt nhất chỉ cho phép [a -zA-Z0-9_] (và bắt một chuỗi rỗng quá). – bobince

0

Vâng, bạn phân tích các tiêu đề email vào một cuốn từ điển. Và sau đó bạn kiểm tra xem Content-Transfer-Encoding có được đặt hay không và nếu nó = "base64" hoặc "base-64".

7

@gnud, @edg - Trừ khi tôi hiểu sai, anh ấy hỏi về tên tệp, không phải nội dung tệp @setori - Nội dung-Trasfer-Encoding đang cho bạn biết cách NỘI DUNG của tệp được mã hóa chứ không phải là "tên tệp ".

Tôi không phải là một chuyên gia, nhưng phần này ở đây trong tên tập tin được nói với ông về các nhân vật tiếp theo:?

= GB2312 B?

Tôi đang tìm tài liệu trong RFC ... Ah! ở đây là: http://tools.ietf.org/html/rfc2047

Các RFC nói:

Nói chung, một "mã hóa-word" là một chuỗi các ký tự ASCII in bắt đầu với, kết thúc bằng, và "=?" "=?" có hai "?" s ở giữa.

Cái gì khác để nhìn vào là mã trong SharpMimeTools, một phân tích cú pháp MIME (trong C#) mà tôi sử dụng trong ứng dụng bug tracking tôi, BugTracker.NET

+0

đúng yêu cầu sau khi tên tệp không phải là nội dung, tôi chưa bao giờ gặp vấn đề với điều đó, mặc dù nó có ký tự tiếng Trung trong đó. vì nó là tất cả base64 – Setori

21

Giá trị tiêu đề nói với bạn điều này:

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

Vì vậy, chia nhỏ trên "?" thực sự được bạn này (JSON ký hiệu)

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

Trong mảng kết quả, nếu "B" là về vị trí thứ 2, bạn phải đối mặt với một chuỗi cơ sở-64 được mã hóa vào vị trí 3. Khi bạn giải mã nó, hãy chắc chắn để trả chú ý đến mã hóa ở vị trí 1, có lẽ tốt nhất là nên chuyển đổi toàn bộ nội dung sang UTF-8 bằng cách sử dụng thông tin đó.

+0

đẹp, bắt đầu từ 0 –

+2

Có cách nào khác không? ;-) – Tomalak

+0

Câu trả lời này có dựa trên tài liệu ủy quyền không? – Deestan

0

Câu hỏi: "" "Ngoài ra tôi thực sự cần phải biết những gì loại của tập tin đó là .xls tức hoặc .doc vì vậy tôi cần phải giải mã các tên tập tin để xử lý một cách chính xác tập tin đính kèm, nhưng như trên, dường như gb2312 không được hỗ trợ trong jython, biết bất kỳ roundabouts?"""

dữ liệu:

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

Quan sát:

(1) Dòng đầu tiên chỉ ra Microsoft Excel, vì vậy .xls đang tìm kiếm tốt hơn so với .doc

(2)

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

(a) Tiện ích mở rộng dường như là .xls - không cần codec gb2312
(b) Nếu bạn muốn có tên tệp an toàn cho hệ thống tệp, bạn có thể sử dụng biến thể "-_" của base64 HOẶC bạn có thể mã hóa phần trăm
(c) những gì nó có giá trị, tên tập tin là XYhenXYg.xls trong đó X và Y là 2 ký tự Trung Quốc cùng nhau có nghĩa là "bản sao" và phần còn lại là các ký tự ASCII theo nghĩa đen.

Các vấn đề liên quan