2015-12-15 61 views
0

我正在使用Mandrill入站電子郵件API,並且當電子郵件的文件名中包含一個或多個空格的附件時,文件名將以我不知道如何解碼。如何解碼Ruby中的字符串

下面是一個例子字符串我收到的文件名:=?UTF-8?B?TWlzc2lvbmFyecKgRmFpdGjCoFByb21pc2XCoGFuZMKgQ2FzaMKgUmVjZWlwdHPCoFlURMKgMjUzNQ==?= =?UTF-8?B?OTnCoEp1bHktMjAxNS5jc3Y=?=

我想Base64.decode64(#{encoded_value}),但沒有返回一個可讀的文本。

如何將該值解碼爲可讀的字符串?

+0

定義這將是有益的,如果你能告訴我們你在談論的算法。 –

+0

使用mime解碼器,只是爲你提供一個線索:'放入Base64。decode64(「TWlzc2lvbmFyecKgRmFpdGjCoFByb21pc2XCoGFuZMKgQ2FzaMKgUmVjZWlwdHPCoFlURMKgMjUzNQ ==」)'產生'傳教信仰承諾和現金收據年初至今2535' –

回答

1

這是MIME encoded-word syntaxRFC-2822定義。維基百科:

的形式是: 「=?字符集?編碼?編碼的文本?=」。

  • 字符集可以是與IANA註冊的任何字符集。通常情況下,它與消息正文是相同的字符集。
  • 編碼可以是「Q」表示Q-編碼要麼是類似於quoted-printable編碼,或「B」表示base64編碼。
  • 編碼文本是Q編碼或base64編碼的文本。

幸運的是,您不需要爲此編寫解碼器。該Mail寶石配有Mail::Encodings.value_decode方法,完美的作品,是非常well-tested

subject = "=?UTF-8?B?TWlzc2lvbmFyecKgRmFpdGjCoFByb21pc2XCoGFuZMKgQ2FzaMKgUmVjZWlwdHPCoFlURMKgMjUzNQ==?= =?UTF-8?B?OTnCoEp1bHktMjAxNS5jc3Y=?=" 
Mail::Encodings.value_decode(subject) 
# => "Missionary Faith Promise and Cash Receipts YTD 253599 July-2015.csv" 

它優雅地處理大量的邊緣情況下,你可能不會想到的(直到您的應用程序試圖處理他們倒下):

subject = "Re:[=?iso-2022-jp?B?GyRCJTAlayE8JV0lcyEmJTglYyVRJXMzdDwwMnEbKEI=?=\n =?iso-2022-jp?B?GyRCPFIbKEI=?=] =?iso-2022-jp?B?GyRCSlY/LiEnGyhC?=\n =?iso-2022-jp?B?GyRCIVolMCVrITwlXSVzIVskKkxkJCQ5ZyRvJDsbKEI=?=\n =?iso-2022-jp?B?GyRCJE43byRLJEQkJCRGIUolaiUvJSglOSVIGyhC?=#1056273\n =?iso-2022-jp?B?GyRCIUsbKEI=?=" 
Mail::Encodings.value_decode(subject) 
# => "Re:[グルーポン・ジャパン株式會社] 返信:【グルーポン】お問い合わせの件について(リクエスト#1056273\n )" 

如果您使用的是Rails,您已經擁有Mail gem。否則,只需將gem "mail"添加到您的Gemfile,然後bundle install,並在您的腳本中添加require "mail"

1

感謝來自@ Yevgeniy-Anfilofyev的評論,他指出了我的正確方向,我能夠編寫以下方法,正確解析編碼值並返回ASCII字符串。

def self.decode(value) 
    # It turns out the value is made up of multiple encoded parts 
    # so we first need to split each part so we can decode them seperately 
    encoded_parts = name.split('=?UTF-8?B?'). 
         map{|x| x.sub(/\?.*$/, '') }. 
         delete_if{|x| x.blank? } 

    encoded_parts.map{|x| Base64.decode64(x)}. # decode each part 
       join(''). # join the parts together 
       force_encoding('utf-8'). # force UTF-8 encoding 
       gsub("\xC2\xA0", " ") # remove the UTF-8 encoded spaces with an ASCII space 
end 
+0

當編碼不是UTF-8時,此代碼是否失敗? –

-1

我想只是爲了糾正我上面看到的信息...... RFC 2822實際上對SMTP協議進行了回顧,具體而言,編碼字在RFC 1342

https://tools.ietf.org/html/rfc1342

+1

這應該是對答案的評論,而不是新的答案。 –