Генерация хэша фиксированной длины в python для параметра url - PullRequest
10 голосов
/ 08 апреля 2010

Я работаю в Python на Appengine.

Я пытаюсь создать то, что эквивалентно значению "v" в URL-адресе YouTube (http://www.youtube.com/watch?v=XhMN0wlITLk) для извлечения конкретных объектов. Автоматическое хранилище данных генерирует ключ, но он слишком длинный (34 цифры). Я экспериментировал с hashlib, чтобы создать свой собственный, но снова получаю длинную строку. Я хотел бы сохранить ее до 11 цифр (я не имею дело с огромным количеством сущностей), и буквы и цифры приемлемы.

Кажется, должно быть довольно стандартное решение. Я, наверное, просто скучаю по нему.

Ответы [ 2 ]

8 голосов
/ 08 апреля 2010

Вы можете использовать автоматически сгенерированный целочисленный идентификатор ключа для генерации хеша. Простой способ создать хеш - преобразовать целочисленный идентификатор в base62 (буквенно-цифровой). Чтобы получить объект, просто конвертируйте его в base десятичное обратно и используйте get_by_id для получения объекта.

Вот простая функция преобразования base62, которую я использовал в одном из моих приложений.

import string
alphabet = string.letters + string.digits
max = 11

def int_to_base62(num):
    if num == 0:
        return alphabet[0]

    arr = []
    radix = len(alphabet)
    while num:
        arr.append(alphabet[num%radix])
        num /= radix
    arr.reverse()
    return (alphabet[0] * (max - len(arr))) + ''.join(arr)

def base62_to_int(str):
    radix = len(alphabet)
    power = len(str) - 1
    num = 0
    for char in str:
        num += alphabet.index(char) * (radix ** power)
        power -= 1
    return num
6 голосов
/ 08 апреля 2010

Если у вас есть значение, уникальное для каждой сущности, вы можете получить более короткую версию, хешируя ее и обрезая. Хеши, такие как md5 или sha1, хорошо перемешаны, это означает, что каждый бит на выходе имеет 50% -ную вероятность переворачивания, если вы измените один бит на входе. Если вы усекаете хэш, вы просто увеличиваете шансы на столкновение, но вы можете сделать компромисс между длиной и шансами на столкновение.

Url-безопасное кодирование base64 является хорошим вариантом для преобразования хеша в текст.

orig_id = 'weiowoeiwoeciw0eijw0eij029j20d232weifw0jiw0e20d2' # the original id
shorter_id = base64.urlsafe_b64encode(hashlib.md5(orig_id).digest())[:11]

С base64 у вас есть 6 бит информации на символ, 11 символов дают вам 66 бит уникальности или шанс столкновения 1 в 2 ** 66.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...