Как я могу сделать уникальный URL-адрес в Python a la http://imgur.com/gM19g или http://tumblr.com/xzh3bi25y При использовании uuid из python я получаю очень большой. Я хочу что-то более короткое для URL-адресов.
Как сделать уникальный короткий URL с Python?
Ответ 1
Изменить. Здесь я написал для вас модуль. Используй это. http://code.activestate.com/recipes/576918/
Подсчет с 1 гарантирует короткие уникальные URL./1,/2,/3... и т.д.
Добавление прописных и строчных букв к вашему алфавиту даст URL-адреса, подобные тем, которые указаны в вашем вопросе. И вы просто рассчитываете в base-62 вместо base-10.
Теперь единственная проблема заключается в том, что URL-адреса идут последовательно. Чтобы исправить это, прочитайте мой ответ на этот вопрос здесь:
Карта, увеличивающая целочисленный диапазон до шестизначной базы 26 макс, но непредсказуемо
В основном подход состоит в том, чтобы просто обменивать биты вокруг в увеличивающемся значении, чтобы создать видимость случайности, сохраняя детерминизм и гарантируя, что у вас нет никаких столкновений.
Ответ 2
Я не уверен, что большинство сокращений URL используют случайную строку. Мое впечатление заключается в том, что они пишут URL-адрес базы данных, затем используют целочисленный идентификатор новой записи как короткий URL-адрес, закодированную базу 36 или 62 (буквы + цифры).
Код Python для преобразования int в строку в произвольных базах здесь.
Ответ 3
Этот модуль будет делать то, что вы хотите, гарантируя, что строка глобально уникальна (это UUID):
http://pypi.python.org/pypi/shortuuid/0.1
Если вам нужно что-то более короткое, вы сможете укоротить его до желаемой длины и при этом получить что-то, что, вероятно, позволит избежать столкновений.
Ответ 4
Этот ответ приходит довольно поздно, но я наткнулся на этот вопрос, когда планировал создать проект сокращения URL. Теперь, когда я реализовал полностью функциональное средство сокращения URL-адресов (исходный код amitt001/pygmy), я добавляю здесь ответ для других.
Основной принцип, используемый для сокращения URL-адресов, заключается в том, чтобы получить int из длинного URL-адреса, а затем использовать кодировку base62 (base32 и т.д.) Для преобразования этого int в более читаемый короткий URL-адрес.
Как генерируется этот int?
Большинство средств сокращения URL-адресов использует автоинкрементное хранилище данных для добавления URL-адреса в хранилище данных и использует идентификатор автоинкремента для получения кодировки base62 для int.
Пример кодировки base62 из строковой программы:
# Base-62 hash
import string
import time
_BASE = 62
class HashDigest:
"""Base base 62 hash library."""
def __init__(self):
self.base = string.ascii_letters + string.digits
self.short_str = ''
def encode(self, j):
"""Returns the repeated div mod of the number.
:param j: int
:return: list
"""
if j == 0:
return [j]
r = []
dividend = j
while dividend > 0:
dividend, remainder = divmod(dividend, _BASE)
r.append(remainder)
r = list(reversed(r))
return r
def shorten(self, i):
"""
:param i:
:return: str
"""
self.short_str = ""
encoded_list = self.encode(i)
for val in encoded_list:
self.short_str += self.base[val]
return self.short_str
Это только частичный код, показывающий кодировку base62. Ознакомьтесь с полным кодом кодировки/декодирования base62 по адресу core/hashdigest.py
Все ссылки в этом ответе сокращены из проекта, который я создал
Ответ 5
Python short_url является удивительным.
Вот пример:
import short_url
id = 20 # your object id
domain = 'mytiny.domain'
shortened_url = "http://{}/{}".format(
domain,
short_url.encode_url(id)
)
И для декодирования кода:
decoded_id = short_url.decode_url(param)
Что это:)
Надеюсь, это поможет.
Ответ 6
Причина UUID длинна, потому что они содержат много информации, чтобы гарантировать, что они могут быть уникальными во всем мире.
Если вам нужно что-то более короткое, вам нужно будет сделать что-то вроде генерации случайной строки, проверяя, находится ли она в юниверсе уже сгенерированных строк, и повторяя, пока не получите неиспользуемую строку. Вам также нужно будет следить за concurrency здесь (что, если одна и та же строка генерируется отдельным процессом перед вставкой в набор строк?).
Если вам нужна помощь в создании случайных строк в Python, этот другой вопрос может помочь.
Ответ 7
Hashids - это отличный инструмент для этого.
Edit:
Здесь, как использовать Hashids для создания уникального короткого URL-адреса с Python:
from hashids import Hashids
pk = 123 # Your object id
domain = 'imgur.com' # Your domain
hashids = Hashids(salt='this is my salt', min_length=6)
link_id = hashids.encode(pk)
url = 'http://{domain}/{link_id}'.format(domain=domain, link_id=link_id)
Ответ 8
На самом деле не важно, что это Python, но вам просто нужна хеш-функция, которая отображает нужную длину. Например, возможно, используйте MD5, а затем возьмите только первые символы n
. Однако вам придется следить за конфликтами в этом случае, поэтому вы можете выбрать что-то более надежное с точки зрения обнаружения столкновений (например, используя простые числа, чтобы циклически перемещаться по пространству хэш-строк).
Ответ 9
Я не знаю, можете ли вы это использовать, но мы создаем объекты контента в Zope, которые получают уникальные числовые идентификаторы на основе текущих временных строк, в миллисекундах (например, 1254298969501).
Возможно, вы можете догадаться об остальном. Используя рецепт, описанный здесь: Как преобразовать целое число в кратчайшую безопасную строку в Python?, мы кодируем и декодируем реальный идентификатор "на лету", без необходимости хранения. Например, 13-значное целое число сокращается до 7 буквенно-цифровых символов в базе 62.
Чтобы завершить реализацию, мы зарегистрировали короткое (xxx.yy) доменное имя, которое декодирует и перенаправляет 301 для "не найденных" URL-адресов,
Если бы я начинал, я бы вычитал "начальное" время (в миллисекундах) с числового id до кодирования, а затем повторно добавлял его при декодировании. Или же при создании объектов. Без разницы. Это было бы короче..
Ответ 10
Попробуйте http://code.google.com/p/tiny4py/... Он все еще находится в разработке, но очень полезен!!
Ответ 11
Моя цель: Создать уникальный идентификатор указанной фиксированной длины, состоящий из символов 0-9
и a-z
. Например:
zcgst5od
9x2zgn0l
qa44sp0z
61vv1nl5
umpprkbt
ylg4lmcy
dec0lu1t
38mhd8i5
rx00yf0e
kc2qdc07
Вот мое решение. (Адаптировано из этого kmkaplan.)
import random
class IDGenerator(object):
ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz"
def __init__(self, length=8):
self._alphabet_length = len(self.ALPHABET)
self._id_length = length
def _encode_int(self, n):
# Adapted from:
# Source: /questions/41819/how-to-convert-an-integer-to-the-shortest-url-safe-string-in-python/301594#301594
# Author: https://stackoverflow.com/users/50902/kmkaplan
encoded = ''
while n > 0:
n, r = divmod(n, self._alphabet_length)
encoded = self.ALPHABET[r] + encoded
return encoded
def generate_id(self):
"""Generate an ID without leading zeros.
For example, for an ID that is eight characters in length, the
returned values will range from '10000000' to 'zzzzzzzz'.
"""
start = self._alphabet_length**(self._id_length - 1)
end = self._alphabet_length**self._id_length - 1
return self._encode_int(random.randint(start, end))
if __name__ == "__main__":
# Sample usage: Generate ten IDs each eight characters in length.
idgen = IDGenerator(8)
for i in range(10):
print idgen.generate_id()
Ответ 12
Вы можете сгенерировать N случайную строку:
import string
import random
def short_random_string(N:int) -> str:
return ''.join(random.SystemRandom().choice(string.ascii_uppercase +string.ascii_lowercase+ string.digits) for _ in range(N))
вывод для N = 10:
'G1ZRbouk2U'