Comment créer une URL courte unique avec Python?

Comment puis-je faire une URL unique en Python a la http://imgur.com/gM19g ou http://tumblr.com/xzh3bi25y Quand j'utilise uuid de python, j'en obtiens un très grand. Je veux quelque chose de plus court pour les URLs.

28
demandé sur CloudyMarble 2009-09-30 15:16:10

11 réponses

Modifier : Ici, j'ai écrit un module pour vous. Utiliser. http://code.activestate.com/recipes/576918 /


Compter à partir de 1 garantira des URLS courtes et uniques. / 1, /2, / 3 ... etc.

ajouter des lettres majuscules et minuscules à votre alphabet donnera des URLs comme celles de votre question. Et vous ne comptez que la base-62 au lieu de la base-10.

Now le seul problème est que les URLs viennent consécutivement. Pour corriger cela, lire ma réponse à cette question ici:

Carte entier augmentant gamme à six chiffres de la base de 26 max, mais de façon imprévisible

fondamentalement, l'approche consiste simplement à échanger des bits dans la valeur incrémentielle pour donner l'apparence de l'aléatoire tout en maintenant le déterminisme et en garantissant que vous n'avez pas de collisions.

22
répondu FogleBird 2017-05-23 11:45:36

Je ne suis pas sûr que la plupart des raccourcisseurs D'URL utilisent une chaîne aléatoire. Mon impression est qu'ils écrivent L'URL à une base de données, puis utilisent L'ID entier du nouvel enregistrement comme URL courte, encodé base 36 ou 62 (lettres+chiffres).

code Python pour convertir Un int en chaîne dans des bases arbitraires est ici .

16
répondu Ned Batchelder 2009-09-30 11:24:40

ce module fera ce que vous voulez, garantissant que la chaîne est globalement unique (C'est un UUID):

http://pypi.python.org/pypi/shortuuid/0.1

si vous avez besoin de quelque chose de plus court, vous devriez être en mesure de le tronquer à la longueur désirée et encore obtenir quelque chose qui permettra raisonnablement probablement d'éviter les affrontements.

4
répondu Stavros Korokithakis 2011-01-09 17:41:46

la raison pour laquelle les UUIDs sont longs est qu'ils contiennent beaucoup d'informations de sorte qu'ils peuvent être garantis d'être unique à l'échelle mondiale.

si vous voulez quelque chose de plus court, alors vous aurez besoin de faire quelque chose comme générer une chaîne aléatoire, vérifier si elle est dans l'univers des chaînes déjà générées, et répéter jusqu'à ce que vous obtenez une chaîne inutilisée. Vous aurez également besoin de faire attention à la concurrence ici (et si la même chaîne est générée par un processus séparé avant que vous inséré dans le jeu de cordes?).

si vous avez besoin d'aide pour générer des chaînes aléatoires en Python, cette autre question pourrait vous aider.

2
répondu Dominic Rodger 2017-05-23 12:34:04

Hashids est un excellent outil pour cela.

Edit:

Voici comment utiliser Hashids pour générer une URL courte unique avec Python:

from hashids import Hashids

pk = 123 # Your object's 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)
2
répondu yndolok 2015-08-10 15:52:24

ce N'est pas vraiment important que ce soit Python, mais vous avez juste besoin d'une fonction de hachage qui correspond à la longueur que vous voulez. Par exemple, peut-être utiliser MD5 et puis prendre seulement les premiers caractères n . Vous devrez faire attention aux collisions dans ce cas, donc vous pourriez choisir quelque chose d'un peu plus robuste en termes de détection de collision (comme utiliser des nombres premiers pour parcourir l'espace des chaînes de hachage).

1
répondu G Gordon Worley III 2009-09-30 11:21:54

Je ne sais pas si vous pouvez utiliser cela, mais nous générons des objets de contenu dans Zope qui obtiennent des identifiants numériques uniques basés sur les chaînes de temps actuelles, en millis (eg, 1254298969501)

Peut-être que vous pouvez deviner le reste. Utilisation de la recette décrite ici: comment convertir un entier en la plus courte chaîne de caractères en Python? , nous encodons et décodons le vrai id à la volée, sans besoin de stockage. Un entier de 13 chiffres est réduit à 7 caractères alphanumériques en base 62, par exemple.

pour compléter la mise en œuvre, nous avons enregistré un short (xxx.yy) nom de domaine, qui décode et fait une redirection 301 pour "URLs pas trouvé", 151910920"

si je recommençais, je soustrais le temps de" redémarrage " (en millis) de l'id numérique avant l'encodage, puis je le rajoute lors du décodage. Ou bien lors de la génération des objets. Quoi. Ce serait beaucoup plus court..

1
répondu Ken 2017-05-23 12:00:20

Python short_url est génial.

voici un exemple:

import short_url

id = 20  # your object id
domain = 'mytiny.domain' 

shortened_url = "http://{}/{}".format(
                                     domain,
                                     short_url.encode_url(id)
                               )

et de décoder le code:

decoded_id = short_url.decode_url(param)

:)

Espérons que cela aidera.

1
répondu Hasan Agha 2017-11-09 09:41:10

Essayez cette http://code.google.com/p/tiny4py/ ... Il est encore en développement, mais très utile!!

0
répondu Erenwoid 2011-03-31 00:43:03

Mon Objectif: Générer un identifiant unique d'une longueur fixe comprenant les caractères 0-9 et a-z . Par exemple:

zcgst5od
9x2zgn0l
qa44sp0z
61vv1nl5
umpprkbt
ylg4lmcy
dec0lu1t
38mhd8i5
rx00yf0e
kc2qdc07

voici ma solution. (adaptation de cette réponse par 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: https://stackoverflow.com/a/561809/1497596
        #   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()
0
répondu DavidRR 2017-05-23 12:01:58

je sais que cette réponse arrive assez tard, mais je suis tombé sur cette question quand j'avais l'intention de créer un projet de raccourci D'URL. Maintenant que j'ai implémenté un projet de raccourci D'URL entièrement fonctionnel (code source à amitt001/pygmy c'est en Python 3), j'ajoute une réponse que comment c'est fait. Pour aider quelqu'un d'autre:

le principe de base derrière n'importe quel shortener D'URL est d'obtenir un int de long URL puis utiliser base62 (base32, etc) encodage pour convertir cet int en une URL courte plus lisible.

comment cette int est-elle générée? La plupart des raccourcisseurs D'URL utilisent un datastore incrémentant automatiquement pour ajouter des URL à datastore et utilisent l'id d'autoincrement pour obtenir l'encodage de base62 de int.

L'exemple de base62 l'encodage d'une chaîne de programme:

# 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

c'est juste un code partiel et il ne montre pas comment base62 est décodé. Consultez le code d'encodage complet de base62 à core/hashdigest.py

tout le lien dans cette réponse sont abrégés du projet que j'ai créé

0
répondu Amit Tripathi 2017-12-11 19:58:34