Python: закодируйте строку в короткую бессмысленную строку обратимым образом - PullRequest
2 голосов
/ 20 января 2011

Я прошу прощения за общий вопрос (у меня нет никаких прошлых знаний о сжатии, и я не знаю, есть ли у него возможное решение).

У меня есть несколько кодов из 19 символов.

Эти символы могут быть только: A-Z, a-z, 0-9, ., :, -

Примером может быть что-то вроде 1995AbC...123..456Z

Я хочу найти способ обратимым образом преобразовать эту строку в более короткую, содержащую только символы ascii: что-то вроде gfSDd2H.

  • Возможно ли это?
  • Есть ли способ сделать это в Python?

Спасибо!

Ответы [ 3 ]

5 голосов
/ 20 января 2011

Вы можете попробовать сжать строку и закодировать результат, например, в base64. Это, конечно, предполагает, что ваши исходные строки являются сжимаемыми. Для строк из 19 символов это кажется маловероятным.

Если вам разрешено сохранять некоторые данные, вы можете сжать первую строку до 1, второй до 2 и т.д. , Затем вы можете закодировать число в виде строки 64 (или другой базовой).

Это похоже на работу сервисов сокращения URL.

4 голосов
/ 20 января 2011

Вы допускаете 65 различных символов.Предполагая, что все входы имеют одинаковую вероятность, каждое кодирование даст не менее 19 * 65/128 ≈ 10 символов.Однако, поскольку вы, вероятно, хотите игнорировать непечатаемые символы, это число уменьшено до 19 * 65/95 = 13 символов с идеальным отображением.Следовательно, любое такое отображение не приведет к значительному сокращению пространства.

2 голосов
/ 20 января 2011

Конечно (?) Это возможно в 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...