2011-01-19 63 views
2

我对通用的问题(我没有关于压缩任何过去的知识,我不知道是否有一个可能的解决方案)对不起。的Python:代码串短串无意义可逆的方式

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

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

一个例子可以是这样的1995AbC...123..456Z

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

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

谢谢!

+1

对数据有一些更高级的含义吗?各种领域的连接可能具有更大的结构?你想要/需要压缩的动机是什么? – 2011-01-19 23:34:09

+0

是的,这段代码是Bibcode(http://en.wikipedia.org/wiki/Bibcode),我想压缩它的原因是因为我在包含这段代码的URL时遇到了一些问题。 – 2011-01-20 14:48:30

回答

5

你可以尽量压缩字符串,并将结果与​​例如的base64编码。这当然假定你的原始字符串是可压缩的。对于19个字符的字符串,这似乎不太可能

如果你被允许继续存在的一些数据,你可以第一个字符串压缩到1,第二个为2,等等,你将需要保存您在由例如数据库的映射,这样就可以逆转它。然后,您可以将该数字编码为基本64(或其他基本)字符串。

这类似于如何URL缩短服务工作。

4

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

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 = "ABCetcXYZabcetcxyz.:-" 
b65_padsize = 19