Я работаю в Python над appengine.
Я пытаюсь создать то, что эквивалентно значению "v" в URL YouTube (http://www.youtube.com/watch?v=XhMN0wlITLk) для получения определенных объектов. Автоматическое хранилище данных генерирует ключ, но это слишком длинно (34 цифры). Я экспериментировал с hashlib для создания моего собственного, но снова я получаю длинную строку. Я хотел бы сохранить его к под 11 цифрами (я не имею дело с огромным количеством объектов), и буквы, и числа приемлемы.
Кажется, что должно быть довольно стандартное решение. Я, вероятно, просто пропускаю его.
Вы можете использовать автоматически сгенерированный целочисленный идентификатор ключа для генерации хэша. Простой способ сгенерировать хеш - преобразовать целочисленный идентификатор в base62 (буквенно-цифровой). Чтобы получить объект, просто преобразуйте его в десятичное число из base62 и используйте 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
Если у вас есть значение, которое уникально для каждой сущности, вы можете получить более короткую версию, хэшируя его и усекая. Такие хэши, как 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.