Вопрос по string, numeric, python, encode – Кодирование числовой строки в сокращенную буквенно-цифровую строку и обратно

7

Быстрый вопрос. Я пытаюсь найти или написать кодировщик в Python, чтобы сократить строку чисел, используя буквы верхнего и нижнего регистра. Числовые строки выглядят примерно так:

<code>20120425161608678259146181504021022591461815040210220120425161608667
</code>

Длина всегда одинакова.

Сначала я хотел написать простой кодировщик, который использовал бы заглавные и строчные буквы и цифры, чтобы сократить эту строку до чего-то, похожего на это:

<code>a26Dkd38JK
</code>

Это было совершенно произвольно, просто пытаться быть максимально понятным. Я уверен, что есть действительно удобный способ сделать это, возможно, уже встроенный. Может быть, это неловкий вопрос, который даже нужно задавать.

Кроме того, мне нужно иметь возможность взять сокращенную строку и преобразовать ее обратно в более длинное числовое значение. Должен ли я что-то написать и опубликовать код, или это встроенная функция Python, о которой я уже должен знать?

Спасибо!

base64 JBernardo
Дж. Бернардо прибил его. Отправьте это как ответ :) !! David Robinson
Дж. Бернардо - Спасибо за предложение, но, как указывает Дэвид, использование base64 не является решением моей проблемы, поскольку фактически значительно удлиняет строку. Цель здесь - сократить его. Ryan Martin
(На самом деле, просто использование base64 само по себе удлиняет строку) David Robinson
Хорошо, что вы предлагаете сами написать код и опубликовать его здесь. Julian

Ваш Ответ

3   ответа
10

import base64

def num_to_alpha(num):
    num = hex(num)[2:].rstrip("L")

    if len(num) % 2:
        num = "0" + num

    return base64.b64encode(num.decode('hex'))

Сначала он превращает целое число в строку байтов, а затем base64 кодирует его. Вот декодер:

def alpha_to_num(alpha):
    num_bytes = base64.b64decode(alpha)
    return int(num_bytes.encode('hex'), 16)

Пример:

>>> num_to_alpha(20120425161608678259146181504021022591461815040210220120425161608667)
'vw4LUVm4Ea3fMnoTkHzNOlP6Z7eUAkHNdZjN2w=='
>>> alpha_to_num('vw4LUVm4Ea3fMnoTkHzNOlP6Z7eUAkHNdZjN2w==')
20120425161608678259146181504021022591461815040210220120425161608667
+1. Обратите внимание, что для этого требуется int, а не строка
@ ninjagecko: я не понимаю, почему для этого нужны целые числа произвольной точности. Это работает с ними - конечно - но нет части данных функций, которая полагается на целые числа произвольной точности.
Похоже, это прекрасно работает. Именно то, что я искал, спасибо. RE: int vs. string: передача строки в эту функцию на самом деле не работает. Это должно быть Int. Хорошая работа! Ryan Martin
Для этого требуются целые числа произвольной точности, которые, к счастью, есть в python.
@ nightcracker: Да, есть. Тот факт, что вы берете целое число в качестве входных данных в качестве достаточной причины, чтобы требовать целых чисел произвольной точности. Вы можете проверить это самостоятельно, попробовав сделать это на другом языке, таком как javascript без целых чисел произвольной точности. Достаточно большие входные данные будут бессмысленными. Нельзя сказать, что это делает ответ необоснованным на других языках; ответ будет работать для любого входа, который не переполняется. Обычно это не вызывает проблем, но OP использовал строку цифр, которая была бы переполнена в большинстве не-Python языков.
6

base64), но производим более короткий вывод:

chrs = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
l = len(chrs)

def int_to_cust(i):
    result = ''
    while i:
        result = chrs[i % l] + result
        i = i // l
    if not result:
        result = chrs[0]
    return result

def cust_to_int(s):
    result = 0
    for char in s:
        result = result * l + chrs.find(char)
    return result

И результаты:

>>> int_to_cust(20120425161608678259146181504021022591461815040210220120425161608667)
'9F9mFGkji7k6QFRACqLwuonnoj9SqPrs3G3fRx'
>>> cust_to_int('9F9mFGkji7k6QFRACqLwuonnoj9SqPrs3G3fRx')
20120425161608678259146181504021022591461815040210220120425161608667L

Вы также можете сократить сгенерированную строку, если добавите другие символы вchrs переменная.

@RyanMartin: Спасибо.
Я полагаю, вы сами делаете кодировку base 64 вместо использования lib.
Мне очень нравится это решение. Играя с различными предлагаемыми решениями, мне это нравится больше всего, потому что я могу ограничить его только буквами и цифрами и контролировать добавление новых символов в будущем. Красиво сделано. Ryan Martin
@PaulHoang: я думаю, что ваше предположение неверно. Я представил функцию, которая работает аналогичным образом, но 1) без необходимости заполнения (попробуйте удалить=s из ответа nightcracker), 2) с возможностью определения собственных символов, используемых для представления преобразованного значения. Как это работает, очень похоже на base64, но это не base64. Вероятно, есть библиотека, чтобы сделать что-то подобное, но не нашел, какая это.
0
>>> s="20120425161608678259146181504021022591461815040210220120425161608667"
>>> import base64, zlib
>>> base64.b64encode(zlib.compress(s))
'eJxly8ENACAMA7GVclGblv0X4434WrKFVW5CtJl1HyosrZKRf3hL5gLVZA2b'
>>> zlib.decompress(base64.b64decode(_))
'20120425161608678259146181504021022591461815040210220120425161608667'

Похожие вопросы