2010-07-19 6 views
5

che sto cercando di generare UUID con lo stesso stile come URL bit.ly come:Ruby on Rails - generazione di stile bit.ly UUID

http://bit.ly/aUekJP 

o CloudApp quelli:

http://cl.ly/1hVU 

che sono ancora più piccoli

come posso farlo? Ora sto usando UUID gem per ruby, ma non sono sicuro se sia possibile limitare la lunghezza e ottenere qualcosa di simile. Attualmente sto usando questo:

UUID.generate.split("-")[0] => b9386070 

Ma vorrei avere ancora più piccolo e sapendo che sarà unico.

Qualsiasi aiuto sarebbe più o meno apprezzato :)

risposta

14

Stai confondendo due cose diverse qui. Un UUID è un identificatore univoco universale. Ha una probabilità molto alta di essere unico anche se milioni di loro sono stati creati in tutto il mondo allo stesso tempo. Viene generalmente visualizzato come una stringa di 36 cifre. Non puoi tagliare i primi 8 caratteri e aspettarti che sia unico.

Bitly, tinyurl et-al store link e generare un codice breve per rappresentare quel collegamento. Non ricostruiscono l'URL dal codice che cercano in un data-store e restituiscono l'URL corrispondente. Questi non sono UUIDI.

Senza conoscere la propria applicazione è difficile consigliare quale metodo utilizzare, tuttavia è possibile memorizzare qualsiasi cosa si punta in un archivio dati con un tasto numerico e quindi rebase la chiave su base32 utilizzando le 10 cifre e 22 lettere minuscole, magari evitando i problemi di battitura evidenti come 'o' 'i' 'l' ecc

EDIT

Su ulteriori indagini c'è un rubino base32 gem disponibile che implementa Douglas Crockford Base 32 implementation

a 5 la stringa Base32 del personaggio può rappresentare oltre 33 milioni di interi e una stringa di 6 cifre su un miliardo.

+0

grazie per l'informazione Steve, sì, penso di aver davvero frainteso il principio uuid:/la gem di base32 sembra molto carina, sto solo cercando di capire un modo corretto per generare URL brevi basati su ID record, stavo usando un stringa ID prima e assegnandogli il metodo UUID, ma ora penso di poter tornare a un ID intero e quindi se, ad esempio, avvio il conteggio id a 363012, ad esempio, otterrei una rappresentazione di stringa "B2G4" per esso. Spero che questo potrebbe seguire lo stesso come hai spiegato sopra. – zanona

+0

@ludicco. Questo è esattamente quello che stavo dicendo. –

+0

@SteveWeet Grazie per la tua gemma base32 consigliata –

-10

L'unico modo per garantire l'unicità è quello di mantenere un conteggio globale e incrementarlo per ogni uso: 0000, 0001, ecc

+3

Questo non è l'unico modo per garantire l'unicità. –

10

Se si lavora con i numeri, è possibile utilizzare il costruito nel metodi rubino

6175601989.to_s(30) 
=> "8e45ttj" 

per tornare indietro

"8e45ttj".to_i(30) 
=>6175601989 

Quindi non c'è bisogno di memorizzare qualsiasi cosa, si può sempre decodificare un short_code in arrivo.

Questo funziona correttamente per la dimostrazione del concetto, ma non è possibile evitare caratteri ambigui come: 1lji0o. Se stai solo cercando di usare il codice per offuscare gli ID dei record del database, questo funzionerà correttamente. In generale, i codici brevi dovrebbero essere facili da ricordare e trasferire da un supporto all'altro, come leggerli sulla diapositiva di presentazione di qualcuno o ascoltarli al telefono. Se è necessario evitare caratteri difficili da leggere o difficili da "ascoltare", potrebbe essere necessario passare a un processo in cui si genera un codice accettabile e memorizzarlo.

+0

'to_i' accetta un numero massimo di 36, quindi puoi inserire ancora più informazioni in pochi caratteri. – jpadvo

0

ho trovato questo per essere breve e affidabile:

def create_uuid(prefix=nil) 
    time = (Time.now.to_f * 10_000_000).to_i 
    jitter = rand(10_000_000) 
    key = "#{jitter}#{time}".to_i.to_s(36) 
    [prefix, key].compact.join('_') 
end 

Questo sputa fuori chiavi univoche che assomigliano a questo: '3qaishe3gpp07w2m'
Ridurre la dimensione 'jitter' per ridurre la dimensione della chiave.

Caveat: questo non è garantito univoco (utilizzare SecureRandom.uuid per questo), ma è altamente affidabile:

10_000_000.times.map {create_uuid}.uniq.length == 10_000_000