如果您将列表视为字符串,则有11个不同的字符需要编码(0-9和逗号)。这可以用4位表示。如果您愿意将$和!添加到可接受字符列表中,则将有64个不同的输出字符,因此每个字符可以编码6位。
这意味着您可以将字符串映射到经过编码的字符串,其长度约为原始字符串的30%,并且看起来相当混淆和随机。
这样,您可以将数字系列[1,5,8,3,20,212,42]转换为字符串“gLQfoIcIeQqq”。
更新:我感到很有灵感,为此编写了一个python解决方案(不快但足够有效...)
ZERO = ord('0')
OUTPUT_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$!"
def encode(numberlist):
s = str(numberlist).replace(' ','')[1:-1]
four_bit_ints = [0 <= (ord(ch) - ZERO) <= 9 and (ord(ch) - ZERO) + 1 or 11 for ch in s]
four_bits = [bin(x).lstrip('-0b').zfill(4) for x in four_bit_ints]
bin_str = "".join(four_bits)
bin_str = bin_str + '0' * (6 - len(bin_str) % 6)
six_bits = [bin_str[x * 6 : x * 6 + 6] for x in range(0, len(bin_str) / 6)]
six_bit_ints = [int(x, 2) for x in six_bits]
output = "".join([OUTPUT_CHARACTERS[x] for x in six_bit_ints])
return output
def decode(input_str):
six_bit_ints = [OUTPUT_CHARACTERS.index(x) for x in input_str]
six_bits = [bin(x).lstrip('-0b').zfill(6) for x in six_bit_ints]
bin_str = "".join(six_bits)
four_bits = [bin_str[x * 4 : x * 4 + 4] for x in range(0, len(bin_str) / 4)]
four_bit_ints = [int(x, 2) for x in four_bits]
four_bit_ints = [x for x in four_bit_ints if x > 0]
chars = [x < 11 and str(x - 1) or ',' for x in four_bit_ints]
output = [int(x) for x in "".join(chars).split(',') if x]
return output
if __name__ == "__main__":
for i in range(100):
numbers = range(i)
out = decode(encode(numbers))
assert out == numbers
numbers = [1,5,8,3,20,212,42]
encoded = encode(numbers)
print encoded
print decode(encoded)