社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在Python中将数据压缩成最小的文本量

Allen • 6 年前 • 2396 次点击  

def convert_to_ascii85(x):
    p = pickle.dumps(x)
    p = zlib.compress(p)
    return b64.b85encode(p)

我的问题是它生成的字符串比需要的长,因为它只使用字母、数字和符号的子集。如果我能够使用unicode编码,我觉得它可以产生一个较短的字符串,因为它可以访问更多的字符。有办法吗?

我的目标是 不是最小数量的数据/信息/字节 . 我的目标是最少的字符数 . 原因是我发送数据的通道是由字符(精确地说是100k)而不是字节(奇怪,我知道)。我已经测试过可以发送100k个unicode字符,只是不知道如何将字节转换成unicode。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/55221
文章 [ 1 ]  |  最新文章 6 年前
Steve
Reply   •   1 楼
Steve    7 年前

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

更新2:出于对上述内容的好奇,我在谷歌上找到了这个: https://qntm.org/unicodings . 如果你的工具和沟通渠道能够处理UFT-16或UTF-32,那么你可能会在寻求使用它的时候有所收获。如果是这样的话,我希望这篇文章能为您提供您正在寻找的解决方案。我认为本文仍然在针对字节长度和字符长度进行优化,因此这可能无法提供最佳解决方案,但它只能提供帮助(每个字符32个潜在位,而不是7或8)。我找不到任何寻求优化字符计数单独,但也许UTF-32方案,如Base65536是你的答案。退房 https://github.com/qntm/base65536 .

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

Base85非常接近将任意二进制编码为“纯文本”时的最佳效果,如果您希望“纯文本”编码能够在逻辑上分解为有意义的、可预测的块,则它是最佳效果。理论上,您可以使用在高ASCII范围内使用可打印字符的字符集,但经验表明,许多工具和通信通道如果不能处理直接二进制字符,则不能很好地处理高ASCII。尝试每4个二进制字节使用额外的5位,或者使用256位高ASCII而不是128位ASCII,不会节省太多额外的空间。

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

结果是,85个字符是你需要编码4个字节,正好5个可打印字符。许多人会选择增加大约10%的额外长度,以获得这样一个事实,即每4个编码字节将导致正好5个ASCII字符。这只是一个25%的通货膨胀的大小二进制。这对它省下的所有头痛来说一点也不坏。因此,Base85背后的动机。

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

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