2009-09-30 16 views

risposta

2

Il motivo per cui gli UUID sono lunghi è perché contengono molte informazioni in modo che possano essere garantite come uniche al mondo.

Se desideri qualcosa di più breve, dovrai fare qualcosa come generare una stringa casuale, controllare se è nell'universo di stringhe già generate e ripetere fino a ottenere una stringa inutilizzata. Dovrai anche fare attenzione alla concorrenza qui (cosa succede se la stessa stringa viene generata da un processo separato prima di essere inserita nel set di stringhe?).

Se hai bisogno di aiuto per generare stringhe casuali in Python, questo other question potrebbe essere d'aiuto.

1

Non importa che questo sia Python, ma è sufficiente una funzione di hash che si associ alla lunghezza desiderata. Ad esempio, è possibile utilizzare MD5 e quindi prendere solo i primi n caratteri. In questo caso dovrai fare attenzione alle collisioni, quindi potresti scegliere qualcosa di un po 'più robusto in termini di rilevamento delle collisioni (come usare i primi per scorrere lo spazio delle stringhe di hash).

15

Non sono sicuro che la maggior parte degli abbreviazioni URL utilizzi una stringa casuale. La mia impressione è che scrivono l'URL su un database, quindi usano l'ID intero del nuovo record come URL breve, codificato 36 o 62 (lettere + cifre).

Il codice Python per convertire un int in una stringa in basi arbitrarie è here.

22

Modifica: Qui, ho scritto un modulo per te. Usalo. http://code.activestate.com/recipes/576918/


Il conteggio a partire da 1 garantisce URL brevi e univoci./1,/2,/3 ... ecc.

L'aggiunta di lettere maiuscole e minuscole al tuo alfabeto darà URL come quelli nella tua domanda. E stai contando solo in base-62 anziché in base-10.

Ora l'unico problema è che gli URL arrivano consecutivamente. Per rimediare, leggere la mia risposta a questa domanda qui:

Map incrementing integer range to six-digit base 26 max, but unpredictably

Fondamentalmente l'approccio è quello di scambiare semplicemente i bit in giro per il valore di incremento per dare l'apparenza di casualità, pur mantenendo il determinismo e garantendo che non si avere eventuali collisioni.

1

Non so se è possibile utilizzare questo, ma generiamo gli oggetti contenuti in Zope che ottengono gli ID numerici univoci in base a stringhe di tempo in corso, a Millis (ad esempio, 1.254.298,969501 millions)

Forse si può intuire il resto . Usando la ricetta qui descritta: How to convert an integer to the shortest url-safe string in Python?, codifichiamo e decodifichiamo l'id reale al volo, senza necessità di spazio di archiviazione. Un intero di 13 cifre è ridotto a 7 caratteri alfanumerici nella base 62, ad esempio.

Per completare l'implementazione, abbiamo registrato un breve (xxx.yy) nome di dominio, che decodifica e reindirizza 301 per URL "non trovati",

Se dovessi ricominciare, sottrarre il tempo di "avvio" (in millisecondi) dall'ID numerico prima della codifica , quindi aggiungerlo nuovamente durante la decodifica. Oppure quando si generano gli oggetti. Qualunque cosa. Questo sarebbe modo più breve ..

4

Questo modulo sarà fare quello che vuoi, garantendo che la stringa è globalmente univoco (si tratta di un UUID):

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

Se avete bisogno di qualcosa di più breve, si dovrebbe essere in grado di troncarlo alla lunghezza desiderata e ottenere comunque qualcosa che ragionevolmente probabilmente eviterà scontri.

0

mio obiettivo: generare un identificatore univoco di una lunghezza fissa specificato costituita dai caratteri 0-9 e a-z. Ad esempio:

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

Ecco la mia soluzione. (adattato da this answer da kmkaplan.)

import random 

class IDGenerator(object): 
    ALPHABET = "abcdefghijklmnopqrstuvwxyz" 

    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() 
1

Hashids è uno strumento fantastico per questo.

Edit:

Ecco come utilizzare Hashids per generare un breve URL univoco con 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) 
1

di Python short_url è impressionante.

Ecco un esempio:

import short_url 

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

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

E per decodificare il codice:

decoded_id = short_url.decode_url(param) 

Questo è tutto :)

Spero che questo vi aiuterà.

0

So che questa risposta arriva piuttosto tardi, ma mi sono imbattuto in questa domanda quando stavo progettando di creare un progetto URL shortener. Ora che ho implementato un progetto shortener URL completamente funzionale (codice sorgente a amitt001/pygmy è in Python 3), aggiungo una risposta sul modo in cui è stata eseguita. In modo che possa aiutare qualcun altro:

Il principio di base di qualsiasi URL shortener è di ottenere un int dall'URL lungo quindi utilizzare la codifica base62 (base32, ecc.) Per convertire questo int in un URL breve più leggibile.

Come viene generata questa int? La maggior parte del shortener URL utilizza un datastore con incremento automatico per aggiungere l'URL a datastore e utilizzare l'id autoincrement per ottenere la codifica base62 di int.

Il campione base62 codifica dal programma stringa:

# 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 

Questo è solo un codice parziale e non mostra come base62 viene decodificato. Controlla il codice completo di codifica base62 al core/hashdigest.py

Tutto il link in questa risposta si accorciano dal progetto che ho creato

Problemi correlati