2015-12-15 64 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

这应该是对答案的评论,而不是新的答案。 –