使用Ruby,如何将二进制数据转换为高度压缩但可读的格式

时间:2016-05-05 07:01:56

标签: ruby compression information-theory

我有一些二进制数据,我希望将其转换为更易于阅读和复制/匹配的内容。

二进制数据显示如下

?Q?O?,???W%ʐ):?g????????

哪个很难看。我可以将它转换为十六进制:

value.unpack("H*").first

但由于十六进制只有16个字符,所以它不是很压缩。我最终得到了一个长达数百个字符的字符串。

我更喜欢使用字母(大写和小写),数字和基本符号的格式,以充分利用可能的值。我可以使用什么?

我也更喜欢内置于Ruby的东西,它不需要另外的库。不幸的是,我不能要求另一个库,除非它真的是众所周知和流行的,或理想的内置于Ruby。

我尝试了来自http://apidock.com/ruby/String/unpack的内容并找不到任何内容。

3 个答案:

答案 0 :(得分:2)

一种简单的方法使用Base64编码对值进行编码。它与十六进制编码(Base16)非常相似,但使用更长的字典。

Base64字符串在正确准备时仅包含可打印字符。这是复制/粘贴和共享的好处。

第二个好处是它具有3:4的编码率,这意味着它具有合理的效率。 3:4编码比率意味着对于输入中的每3个字节,使用4个字节进行编码(75%有效);十六进制编码是一种效率较低的1:2编码率,或者对于每1字节的输入,使用2个字节进行编码(效率为50%)。

您可以使用Ruby标准库Base64实现进行编码和解码,如下所示:

require "base64"

encoded = Base64.encode64("Taste the thunder!") # <== "VGFzdGUgdGhlIHRodW5kZXIh\n"
decoded = Base64.decode64(encoded)              # <== "Taste the thunder!"

请注意,还有一个(大部分)URL安全版本,因此您可以在URL中的任何位置包含编码值,而无需任何其他URL编码。这将允许您以模糊的方式传递URL中的信息,尤其是通常不会以这种方式传递的信息。

尝试使用此编码数据:

encoded_url_param = Base64.urlsafe_encode64("cake+pie=yummy!")  # <== "Y2FrZStwaWU9eXVtbXkh"
decoded_url_param = Base64.urlsafe_decode64(encoded_url_param)  # <== "cake+pie=yummy!"

在URL中使用Base64,而实际上不是&#34; security&#34;,将有助于防止窥探您的数据和意图。在URL中使用Base64值的唯一潜在缺点是URL必须保持区分大小写,并且某些应用程序不尊重该要求。有关详细信息,请参阅Should URL be case sensitive SO问题。

答案 1 :(得分:1)

听起来像你想要base 64.它是标准库的一部分:

require 'base64'
Base64.encode64(some_data)

或使用pack,

[some_data].pack("m")

结果数据大约是输入大小的4/3。

答案 2 :(得分:1)

Base36字符串编码也是Base64和Hex编码的合理替代方案。在此编码方法中,仅使用36个字符,通常是ASCII小写字母和ASCII编号。

不是专门做这件事的Ruby API,但是这个SO答案Base36 Encode a String展示了如何在Ruby中有效地做到这一点:

编码到Base36:

encoded = data.unpack('H*')[0].to_i(16).to_s(36)

从Base36解码:

decoded = [encoded.to_i(36).to_s(16)].pack 'H*'

Base36编码在URL中使用时效果很好,与Base64类似,但它对Base64的区分大小写问题不敏感。

请注意,不应将Base36字符串编码与基本36基数整数编码混淆,后者只是将整数值转换为相应的基数36编码。整数技术使用String#to_i(36)Fixnum#to_s(36)来实现其目标。