我很抱歉这个通用问题(我没有任何关于压缩的知识,我不知道它是否有可能的解决方案。)
我有一些总共19个字符的代码。
这些字符只能是:A-Z
,a-z
,0-9
,.
,:
,-
示例可以是1995AbC...123..456Z
我想要做的是找到一种方法,以可逆的方式将字符串转换为仅包含ascii字符的较短字符串:类似gfSDd2H
。
谢谢!
答案 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