Как преобразовать целое число в самую короткую URL-безопасную строку в Python? - PullRequest
63 голосов
/ 18 февраля 2009

Я хочу кратчайший способ представления целого числа в URL. Например, 11234 можно сократить до «2be2», используя шестнадцатеричное. Поскольку base64 использует кодировку из 64 символов, должна быть возможность представлять целое число в base64, используя даже меньше символов, чем шестнадцатеричное. Проблема в том, что я не могу найти самый чистый способ преобразования целого числа в base64 (и обратно) с использованием Python.

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

Ответы [ 14 ]

2 голосов
/ 10 августа 2011

Мне нужно было целое число со знаком, поэтому я закончил с:

import struct, base64

def b64encode_integer(i):
   return base64.urlsafe_b64encode(struct.pack('i', i)).rstrip('=\n')

Пример:

>>> b64encode_integer(1)
'AQAAAA'
>>> b64encode_integer(-1)
'_____w'
>>> b64encode_integer(256)
'AAEAAA'
2 голосов
/ 18 февраля 2009

Если вы ищете способ сократить целочисленное представление с использованием base64, я думаю, вам нужно искать в другом месте. Когда вы кодируете что-то с помощью base64, оно не становится короче, а фактически становится длиннее.

например. 11234, закодированный с base64, даст MTEyMzQ =

При использовании base64 вы упустили из виду тот факт, что вы не конвертируете только цифры (0-9) в кодировку 64 символов. Вы конвертируете 3 байта в 4 байта, поэтому вы гарантированно дольше будете кодировать строку в кодировке base64.

1 голос
/ 06 августа 2015

Чистый питон, без зависимостей, без кодирования байтовых строк и т. Д., Просто превращение base 10 int в base 64 int с правильными символами RFC 4648:

def tetrasexagesimal(number):
    out=""
    while number>=0:
        if number == 0:
            out = 'A' + out
            break
        digit = number % 64
        out = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[digit] + out
        number /= 64 # //= 64 for py3 (thank spanishgum!)
        if number == 0:
            break
    return out

tetrasexagesimal(1)
1 голос
/ 18 февраля 2009

Я бы предложил метод «кодировать целое как двоичную строку», а затем метод base64 «Кодировать это», который вы предлагаете, и я бы сделал это, используя структуру:

>>> import struct, base64
>>> base64.b64encode(struct.pack('l', 47))
'LwAAAA=='
>>> struct.unpack('l', base64.b64decode(_))
(47,)

Изменить еще раз: Чтобы убрать лишние 0 для чисел, которые слишком малы, чтобы требовать полной 32-битной точности, попробуйте это:

def pad(str, l=4):
    while len(str) < l:
        str = '\x00' + str
    return str

>>> base64.b64encode(struct.pack('!l', 47).replace('\x00', ''))
'Lw=='
>>> struct.unpack('!l', pad(base64.b64decode('Lw==')))
(47,)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...