【问题标题】:Decode base64 string and write to file解码base64字符串并写入文件
【发布时间】:2014-06-22 16:41:08
【问题描述】:

我正在尝试读取包含编码 base64 字符串的文件并将解码后的输出写入另一个文件。我的Input.txt 包含一个base64 字符串,类似于:

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48cmV2aWV3LWNhc2UgY3JlYXRl\r\nZGF0ZT0iMTMvTWFyLzIwMTQgMDk6MDQ6NTEiIHN5c3RlbT0iVHJhZmlndXJhX1RlbXBsYXRlX01h\r\nbmFnZW1lbnRfdjUuMSIgYmF0Y2hpZD0iMCIgdHJhbnNhY3Rpb25ubz0iMSIgYmF0Y2huYW1lPSJH\r\nVUlEKGY1NWRmYjgwODQ4ZDQ3YzliZmVhYTg3YzMyZDQyNDQyKS1HTE9CQUxfSU5WT0lDRS1FTkdM\r\nSVNIIiB2ZXJzaW9uPSI1LjEuMi44ICBidWlsZCA1MjUzOSI+PHRyYW5zYWN0aW9uPjxvYmplY3Rz\r\nPjxvYmplY3QgY2xhc3M9IlRoXzE5NTQwMDk3OTRfNl9tb2RlbCIgbmFtZT0ibW9kZWwiPjxwcm9w\r\nZXJ0eSBuYW1lPSJUaXRsZSIgdmFsdWU9IlByb3Zpc2lvbmFsIEludm9pY2UiLz48cHJvcGVydHkg\r\nbmFtZT0iR3JvdXBDb21wYW55Ij48b2JqZWN0IGNsYXNzPSJUaF8xOTU0MDA5Nzk0XzZfR3JvdXBD\r\nb21wYW55IiBuYW1lPSJHcm91cENvbXBhbnkiPjxwcm9wZXJ0eSBuYW1lPSJOYW1lIiB2YWx1ZT0i\r\nVHJhZmlndXJhIEJlaGVlciBCLlYuIEFNU1RFUkRBTSwgQlJBTkNIIE9GRklDRSBMVUNFUk5FIi8+\r\nPHByb3BlcnR5IG5hbWU9IkFkZHJlc3MiIHZhbHVlPSJaPz9yaWNoc3RyYXNzZSAzMSIgaW5kZXg9\r\nIjAiLz48cHJvcGVydHkgbmFtZT0iQWRkcmVzcyIgdmFsdWU9Ikx1Y2VybmUiIGluZGV4PSIxIi8+\r\nPHByb3BlcnR5IG5hbWU9IkFkZHJlc3MiIHZhbHVlPSI2MDAyIiBpbmRleD0iMiIvPjxwcm9wZXJ0\r\neSBuYW1lPSJBZGRyZXNzIiB2YWx1ZT0iU3dpdHplcmxhbmQiIGluZGV4PSIzIi8+PHByb3BlcnR5\r\nIG5hbWU9IlBob25lTnVtYmVyIiB2YWx1

此字符串是在服务器端使用 Java apache codec.binary.Base64 库创建的。当两个不同的 Web 服务相互通信时,Fiddler 会捕获此字符串。有时我无法访问另一个 Web 服务,这就是我在服务之间嗅探消息的原因。此外,我使用 Ruby 来自动化一些日常任务,并决定这次再次使用 Ruby。为了编码捕获的 base64 字符串,我使用下一个 sn-p 代码:

require "base64"

content = File.read('Input.txt')
decode_base64_content = Base64.decode64(content) 
File.open("Output.txt", "wb") do |f|
  f.write(decode_base64_content)
end 

但输出看起来格式不正确,例如<?xml version="1.0" encoding="UTF-8"?><review-case create®vFFSТ#2фЦ"у#B“ЈCЈS"7—7FVУТ%G&f–wW&хFVЧЖFUфЦзnagement_v5.1" ba 等等。你能告诉我我做错了什么吗?我在 Windows 7 和 Ubuntu 12.04 上使用 Ruby 1.9.3。

【问题讨论】:

  • 你能完整分享原始的base64编码字符串吗?
  • 恐怕答案是否定的。首先,它包含有关我工作的公司的数据,其次,输入文件包含大约 81.000 个字符。
  • 您的代码看起来不错。尝试执行严格的 decode64,看看它会抛出什么错误。
  • 您是否使用反向方法对原始上下文进行了编码?如果不是,您必须确保使用相同的 Base64 定义。仅在 module Base64 中就至少使用了三个(RFC 2045、RFC 4648(strict_...url safe_... 变体)。
  • @MikeH-R documentation for module Base64 告诉您:“返回 bin 的 Base64 编码版本。此方法符合 RFC 2045。每 60 个编码字符添加换行符。”所以它可能不会期望额外的CR,尝试使用gsub("\r", '') 摆脱它。 decode64 应该(可能)能够处理 76 的行长度。

标签: ruby base64


【解决方案1】:

我不知道您是如何做到这一点的,但您的字符串中的行结尾 \r\n 似乎是 4 字节字符序列,而不是 2 字节转义 CRLF。如果我将您的文件复制到带有单个刻度的红宝石字符串中:

unescaped='PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48cmV2aWV3LWNhc2UgY3JlYXRl\r\nZGF0ZT0iMTMvTWFyLzIwMTQgMDk6MDQ6NTEiIHN5c3RlbT0iVHJhZmlndXJhX1RlbXBsYXRlX01h\r\nbmFnZW1lbnRfdjUuMSIgYmF0Y2hpZD0iMCIgdHJhbnNhY3Rpb25ubz0iMSIgYmF0Y2huYW1lPSJH'
Base64.decode64(unescaped)
#=> garbled text for every second line

如果我对双引号做同样的事情(尊重转义序列):

escaped="PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48cmV2aWV3LWNhc2UgY3JlYXRl\r\nZGF0ZT0iMTMvTWFyLzIwMTQgMDk6MDQ6NTEiIHN5c3RlbT0iVHJhZmlndXJhX1RlbXBsYXRlX01h\r\nbmFnZW1lbnRfdjUuMSIgYmF0Y2hpZD0iMCIgdHJhbnNhY3Rpb25ubz0iMSIgYmF0Y2huYW1lPSJH"
Base64.decode64(escaped)
#=> all is well that ends well

因此,当您写入文件时,似乎会出现问题。不过,它可以在 Ruby 中进行修改:

unescaped='PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48cmV2aWV3LWNhc2UgY3JlYXRl\r\nZGF0ZT0iMTMvTWFyLzIwMTQgMDk6MDQ6NTEiIHN5c3RlbT0iVHJhZmlndXJhX1RlbXBsYXRlX01h\r\nbmFnZW1lbnRfdjUuMSIgYmF0Y2hpZD0iMCIgdHJhbnNhY3Rpb25ubz0iMSIgYmF0Y2huYW1lPSJH'
Base64.decode64(unescaped)
escaped=unescaped.gsub('\\r', "\r").gsub('\\n', "\n")
Base64.decode64(escaped)
#=> now you should be fine again

但当然正确的解决方案是正确存储文件。

鉴于您当前的文件,以下应该可以工作:

require "base64"

content = File.read('Input.txt')
content.gsub!('\\r', "\r")
content.gsub!('\\n', "\n")
decode_base64_content = Base64.decode64(content) 
File.open("Output.txt", "wb") do |f|
  f.write(decode_base64_content)
end

如果没有,请发布一些输出。

【讨论】:

  • 如果我使用双引号并在 ruby​​ 文件中指定编码字符串,它可以工作。但是如果我尝试从文件中获取编码字符串仍然没有成功。谢谢你的帮助。至少它有效,如果没有其他变体建议我应该接受你的回答。
  • @olyv:你的文件怎么是这样写的?您应该使用正确的换行符(在任何约定中)而不是使用转义字符来编写它。如果您在示例代码中读取整个文件,则应该在解码之前添加content.gsub!('\\r', "\r")content.gsub!('\\n', "\n")(注意感叹号,gsub! 将修改字符串而不是创建副本)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-02
  • 2023-03-28
  • 2011-10-18
相关资源
最近更新 更多