python - 字符串压缩 : Output Alphabet Restricted to Alphanumeric Characters

标签 python string compression

我有一个很长的字符串,我想将它压缩成一个新的字符串,但限制是输出字母表只包含[a-z] [A-Z ][0-9] 个字符。

我该怎么做,特别是在 Python 中?

最佳答案

虽然许多编码算法可以采用任意输出范围,但大多数实现不能,如果输出范围不是 2/16/256 的幂,许多算法的效率会低得多。

因此,您想将其分为两部分:首先将一个字节流压缩为另一个字节流。然后将输出字节流编码为字母数字字符。 (如果你从不是字节流的东西开始,比如 Python 3 字符串或 Python 2 unicode,那么第零步就是将它编码成字节流。)

例如,如果你想要 base64,你可以这样做:

import base64, zlib
compressed_bytes = zlib.compress(plain_bytes)
compressed_text = base64.b64encode(compressed_bytes)

不幸的是,您不需要 base-64,因为它包含一些非字母数字字符。

您可以使用 base32 ,它只有大写字母和 6 位数字,对代码的唯一更改是 b32encode 而不是 encode。但这有点浪费,因为它只使用了每 8 位中的 5 位,而理论上您可以使用每 8 位中的 ~5.594 位。

如果您想以最佳方式执行此操作,并且不能仅满足字母数字字符的要求,则 base62 非常复杂,因为您不能逐字节执行,而只能一次处理 7936 字节的 block .那不会很有趣,也不会有效。您可以通过一次分块(例如 32 个字节)并浪费剩余的位来合理地接近最佳状态。但是你最好使用 base64 加上转义机制来处理不适合你的方案的两个字符。例如:

def b62encode(plain):
    b64 = base64.b64encode(plain)
    return b64.replace('0', '00').replace('+', '01').replace('/', '02')

def b62decode(data):
     b64 = '0'.join(part.replace('01', '+').replace('02', '/') 
                    for part in data.split('00'))
     return base64.b64decode(b64)

为了比较,下面是每种算法扩展二进制数据的程度:

  • base32:60.0%
  • 伪造的 base62:39.2%
  • 现实的 base62:~38%
  • 最佳 base62:34.4%
  • base64:33%

像 base64 这样的部分字节传输编码的要点在于它们非常简单并且运行速度很快。虽然您可以将其扩展为像 base62 这样的部分位编码,但您会失去所有优势……因此,如果伪造的 base62 不够好,我建议使用完全不同的东西。


要扭转这一局面,请以相反的顺序扭转所有相同的步骤。

将它们放在一起,使用伪造的 base62,并使用 unicode/Python 3 字符串:

plain_bytes = plain_text.encode('utf-8')
compressed_bytes = zlib.compress(plain_bytes)
b62_bytes = b62encode(compressed_bytes)
b62_text = b62_bytes.decode('ascii')

b62_bytes = b62_text.encode('ascii')
compressed_bytes = b62decode(b62_bytes)
plain_bytes = zlib.decompress(compressed_bytes)
plain_text = plain_bytes.decode('utf-8')

这已经是最复杂的了。

关于python - 字符串压缩 : Output Alphabet Restricted to Alphanumeric Characters,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20507380/

相关文章:

python - 循环范围(0)

jQuery html(text) 通过ajax 解析

c - 如何保留稍后销毁的字符串的内容?

c - 如何正确比较 C 中的字符串?

python - 从现有数据库编码生成 python 的工具?

python - 持有期交易策略盈亏——解决rolling_apply瓶颈

c++ - 在程序中一起使用 getline 和 strtok 的问题

用于提取 .zip 文件的 C++ 包装器代码?

python - 如何将 UPX 与 pyinstaller 一起使用?

compression - Apache Spark 中的 Zip 支持