首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >是否将数据压缩为最小数量的文本?

是否将数据压缩为最小数量的文本?
EN

Stack Overflow用户
提问于 2019-06-24 06:09:01
回答 1查看 1.3K关注 0票数 5

我有一些数据(主要是一系列的numpy数组)想要转换成可以复制/粘贴/通过电子邮件发送的文本。我创建了下面的公式来实现这一点。

代码语言:javascript
复制
def convert_to_ascii85(x):
    p = pickle.dumps(x)
    p = zlib.compress(p)
    return b64.b85encode(p)

我的问题是,它生成的字符串太长,因为它只使用字母、数字和符号的子集。如果我能够使用unicode编码,我觉得它可以生成一个更短的字符串,因为它可以访问更多的字符。有没有办法做到这一点?

编辑以澄清:我的目标不是最小数量的数据/信息/字节。我的目标是最小字符数的。原因是我发送数据的通道是以字符(准确地说是100k)而不是字节(我知道这很奇怪)为上限的。我已经测试过我可以发送100k unicode字符,我只是不知道如何将我的字节转换成unicode。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-24 07:31:48

更新:我刚刚看到你改变了你的问题,以澄清你关心字符长度而不是字节长度。这是一个非常奇怪的约束。我以前从来没听说过。我不知道该怎么理解它。但如果这是您的需求,并且您想要可预测的阻塞行为,那么我认为您的问题非常简单。只需选择可以表示最可能的唯一字符的兼容字符编码,然后在该字符集上映射二进制块,以便每个块都是最长的,并且包含的位数少于字符编码中可表示的字符数。然后,每个这样的块变成单个字符。由于这个约束有点奇怪,我不知道是否有库可以做到这一点。

UPDATE2:出于对上面提到的内容的好奇,我在谷歌上找到了这个:https://qntm.org/unicodings。如果您的工具和通信通道可以处理UFT-16或UTF-32,那么在寻求使用UTF-16或UTF-32时可能会有所收获。如果是这样的话,我希望这篇文章能帮助你找到你想要的解决方案。我认为这篇文章仍然在优化字节长度和字符长度,所以这可能不会提供最佳的解决方案,但它只能提供帮助(每个字符32位,而不是7位或8位)。我找不到任何仅在字符数上寻求优化的方法,但也许像Base65536这样的UTF32方案是您的答案。查看https://github.com/qntm/base65536

如果您关心的是字节长度,并且您想坚持使用通常所指的“可打印字符”或“纯可打印文本”,那么这是我最初的答案……

有一些选项可以从Base85以外的编码中获得更好的“可读文本”编码空间效率。也有理由放弃更多的空间效率,转而使用Base64。在这里,我将说明同时使用Base85和Base64。如果你可以使用Base85,你的二进制文件的膨胀只会有25%的损失,这样你就省去了很多麻烦。

如果您试图将任意二进制编码为“纯文本”,那么Base85非常接近您所能做的最好的结果;如果您想要一种“纯文本”编码,并且可以在逻辑上将其分成有意义的、可预测的块,那么它就是您所能做的最好的选择。从理论上讲,您可以使用使用高ASCII范围内可打印字符的字符集,但是经验表明,如果许多工具和通信通道不能处理普通二进制,那么它们就不能很好地处理高ASCII。尝试使用额外的每4个二进制字节5位,或者使用256位high-ASCII与128位ASCII可能使用的额外空间,并不能节省太多空间。

对于任何BaseXX编码,该算法都会接收传入的二进制位,并使用它所拥有的XX个可打印字符对它们进行尽可能紧密的编码。Base85将比Base64更紧凑,因为它使用了比Base64 (64个字符)更多的可打印字符(85)。

在标准ASCII中有95个可打印字符。所以有一个Base95,它是使用所有可打印字符的最紧凑的编码。但是,尝试使用所有95位是混乱的,因为这会导致传入位的不均匀阻塞。每4个二进制字节被映射到小于5的某个分数个字符。

结果表明,将4个字节编码为恰好5个可打印字符需要85个字符。许多人会选择增加大约10%的额外长度,以实现每4个编码字节恰好导致5个ASCII字符的事实。这只是二进制大小的25%的膨胀。这一点都不坏,因为它省去了所有令人头疼的问题。因此,这就是Base85背后的动机。

Base64用于生成更长但问题更少的编码。不使用对各种文本文档造成麻烦的字符,如HTML、XML、JSON等。通过这种方式,Base64在几乎任何上下文中都很有用,而且没有任何转义。您必须更加小心地使用Base85,因为它不会抛出任何这些有问题的字符。为了提高编码/解码效率,它使用范围33 (“!”)通过117 (‘u’),从33开始,而不是32,只是为了避免经常有问题的空格字符。“u”上面不使用的字符并没有什么特别之处。

这就是二进制-> ASCII码编码方面的故事。另一个问题是,在将其二进制表示编码为ASCII之前,您可以做些什么来减小所表示内容的大小。您选择使用pickle.dumps()zlib.compress()。如果这些是你最好的选择留到下一次讨论...

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56728076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档