Python:以可逆方式将代码字符串转换为更短无意义的字符串

时间:2011-01-19 21:53:12

标签: python compression translation

我很抱歉这个通用问题(我没有任何关于压缩的知识,我不知道它是否有可能的解决方案。)

我有一些总共19个字符的代码。

这些字符只能是:A-Za-z0-9.:-

示例可以是1995AbC...123..456Z

我想要做的是找到一种方法,以可逆的方式将字符串转换为仅包含ascii字符的较短字符串:类似gfSDd2H

  • 有可能吗?
  • 有没有办法在python中做到这一点?

谢谢!

3 个答案:

答案 0 :(得分:5)

您可以尝试压缩字符串并将结果编码为例如base64。这当然假设您的原始字符串是可压缩的。对于19个字符的字符串,这似乎不太可能。

如果你被允许保留一些数据,你可以将第一个字符串压缩为1,将第二个字符串压缩为2,等等......你需要存储你在例如数据库中所做的映射,以便你可以反转它。然后,您可以将该数字编码为基数64(或其他一些基础)字符串。

这与URL缩短服务的工作方式类似。

答案 1 :(得分:4)

您允许65个不同的字符。假设所有输入具有相同的概率,每个编码将产生不小于19 *65/128≈10个字符。但是,由于您可能希望忽略不可打印的字符,因此使用完美映射将其减少到19 * 65/95 = 13个字符。因此,任何此类映射都不会导致空间显着减少。

答案 2 :(得分:2)

当然(?)在Python中是可能的。您所要做的就是将base-65号码转换为base-95或base-94号码,然后再返回。只是它会有点慢,正如另一个答案所指出的那样,你不会节省太多空间

这里(未经测试)是基本构建块:

def ttoi(text, base, letter_values):
    """converts a base-"base" string to an int"""
    n = 0
    for c in text:
        n = n * base + letter_values[c]
    return n

def itot(number, base, alphabet, padsize):
    """converts an int into a base-"base" string
       The result is left-padded to "padsize" using the zero-value character"""
    temp = []
    assert number >= 0
    while number:
        number, digit = divmod(number, base)
        temp.append(alphabet[digit])
    return max(0, padsize - len(temp)) * alphabet[0] + "".join(reversed(temp))

例如您现有的base-65代码:

b65_letter_values = {
    'A': 0, 'Z': 25, 'a': 26, 'z': 51, '0': 52, '9': 61,
    # etc
    }
b65_alphabet = "ABCetcXYZabcetcxyz0123456789.:-"
b65_padsize = 19