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

With Ruby, how to convert binary data to highly compressed, but readable, format

我有一些二进制数据,我想将其转换为更易于阅读和 copy/pastable。

二进制数据显示如下

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

这很丑陋。我可以将它转换为十六进制:

value.unpack("H*").first

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

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

我也更喜欢 Ruby 内置的东西,不需要其他库。不幸的是,我不需要另一个库,除非它真的广为人知和流行,或者理想地内置于 Ruby.

我尝试了 http://apidock.com/ruby/String/unpack 中的内容,但找不到任何内容。

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

Base64 字符串,如果准备得当,只包含可打印的字符。这是 copy/paste 和分享的好处。

第二个好处是它具有 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,而实际上不是 "security",这将有助于防止他人窥探您的数据和意图。在 URL 中使用 Base64 值的唯一潜在缺点是 URL 必须保持区分大小写,而某些应用程序不满足该要求。有关详细信息,请参阅 Should URL be case sensitive SO 问题。

我觉得你想要 base 64。它是标准库的一部分:

require 'base64'
Base64.encode64(some_data)

或使用包,

[some_data].pack("m")

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

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 字符串编码不应与 base 36 基数整数编码混淆,后者只是将整数值转换为相应的 base 36 编码。整数技术使用 String#to_i(36) and Fixnum#to_s(36) 来实现其目标。