Generazione di guide in Ruby


142

Ho un problema che può essere facilmente risolto con le Guide.

In particolare, per un flusso di lavoro di reimpostazione della password, desidero inviare un token Guid all'e-mail di un utente e fare in modo che reimpostino la password utilizzando il token. Dal momento che le guide sono uniche, questo è abbastanza sicuro e mi fa risparmiare e-mail con le password delle persone, il che è rischioso.

Ho notato che esiste una gemma Guid per Ruby; ma sembra piuttosto vecchio e scrive cose nel file system.

Qualcuno sa di altre gemme che possono creare un identificatore univoco globale?

So che posso solo tornare a:

(0..16).to_a.map{|a| rand(16).to_s(16)}.join 

Ma in realtà non sembra un vero GUID ...


1
Usare una stringa casuale come quella non sarebbe del tutto corretto; alcuni bit nell'UUID specificano la variante e la versione. Per un UUID casuale, probabilmente si desidera la variante 2 (RFC 4122) e la versione 4, nel qual caso 6 determinati bit devono essere impostati sui valori corretti.
jtpereyda,

1
Sì, @dafrazzman ha ragione. Mettere insieme in modo casuale qualcosa che "assomiglia a un UUID" non garantisce l'unicità. Sebbene nessun UUID sia veramente garantito, costruirne uno con numeri casuali è molto più suscettibile alle collisioni e non potrebbe essere degno dell'etichetta "UUID". Sicuramente vai con SecureRandom.uuid!
dooleyo,

Risposte:


312

A partire da Ruby 1.9, la generazione di uuid è integrata. Usa la SecureRandom.uuidfunzione

Per esempio:

require 'securerandom'
SecureRandom.uuid # => "96b0a57c-d9ae-453f-b56f-3b154eb10cda"

5
SecureRandom.uuid genera un UUID casuale, quindi non è garantito come unico. Se vuoi solo una stringa casuale che sia probabilmente unica, andrà bene usarla. Tuttavia, se si desidera che qualcosa sia garantito come unico, sarà necessario utilizzare qualcosa che includa l'indirizzo MAC, il timestamp e così via.
Mike Dotterer,

23
Per risparmiare un po 'di ricerca, dovrai richiedere' securerandom '
Jesse Shieh,

8
Non è garantito per essere unico, ma per scopi pratici, è sicuro presumere che sia unico. Vedi: stackoverflow.com/questions/2977593/…
Jesse Shieh

se SecureRandom.uuid segue RFC 4122 come indicato nella documentazione, non significa che ha un campo timestamp? Escludendo la concorrenza, non significa unico?
Michael K Madison,

@MichaelKMadison AFAIK Ruby utilizza la variante "v4" di RFC 4122, che non utilizza un timestamp, quindi la possibilità di una collisione non è davvero nulla - ma in pratica potrebbe anche essere
Edd Morgan


35

Usiamo UUIDTools e non abbiamo problemi con esso.


2
'uuidtools' funziona, anche quando il sistema non ha un indirizzo MAC. 'uuid' fallisce in questo caso.
grefab,

3
A differenza della gemma uuid, uuidtools non mantiene alcun file di stato. I problemi di autorizzazione con il file di stato rendono la gemma uuid un po 'scomoda da usare con più utenti.
Wayne Conrad,

1
Sembra che UUID Tools non sia più gestito. Non c'è stato alcun impegno per il repository github da oltre 2 anni
Sudhanshu Mishra,

22

Hai visto UUIDTools ?

UUIDTools è stato progettato per essere una semplice libreria per generare uno dei vari tipi di UUID (o GUID se si preferisce chiamarli così). È conforme a RFC 4122 quando possibile.


16

Google produce la seguente libreria di Ruby:

http://raa.ruby-lang.org/project/ruby-guid/

Inoltre, su http://www.ruby-forum.com/topic/99262 dicono che è possibile installare un gem (eseguire gem uuidsulla riga di comando per installarlo) e quindi fare

gem 'uuid'
puts UUID.new

nel tuo codice per vedere un nuovo UUID.

(Suggerimento: ho cercato su Google il rubino guid )


grazie l'ho visto ma è super vecchio, solo alla ricerca di qualcosa di attivo, come una gemma recente?
Lance Pollard,

Che ne dici della gemma uuida che ho aggiunto alla mia risposta? O è quello a cui ti riferivi?
Marc W,

5
Questo è strano ... Ho anche cercato su Google "rub ruby", e tutto ciò che ho ottenuto è stato questo post SO :-P
Jason Whitehorn,


3

Piccolo aggiornamento alla risposta di Simone Carletti:

SecureRandom.base64 (8) .gsub ( "/", "_"). Gsub (/ = + $ /, "")

=> "AEWQyovNFo0"

può essere sostituito con:

SecureRandom.urlsafe_base64 (8)


1

Durante la programmazione a tarda notte mi è venuta in mente la seguente soluzione (basata su quella di Simone) per generare un GUID unico in Rails. Non ne vado fiero ma funziona abbastanza bene.

while Order.find_by_guid(guid = rand(36**8).to_s(36).upcase).present?; end

2
Spero che ti sia ricordato di indicizzare la tua colonna guida quella notte
Nurettin,

0

Quando ho usato le gemme uuid consigliate in questa domanda, nessuno può generare UUID unici e casuali. La mia risposta è una soluzione: se avremo gemma più tardi per soddisfare la richiesta, è meglio usare gemma in Ruby.

Ho provato le gemme di uuidi più raccomandate in questa domanda, ma nessuno mi rende soddisfatto, abbiamo bisogno di uuidi unici e casuali. Eseguo direttamente il comando di sistema uuidgenin ruby ​​e mi piace il risultato e lo condivido qui.

puts `uuidgen`
8adea17d-b918-43e0-b82f-f81b3029f688
puts `uuidgen`
6a4adcce-8f64-41eb-bd7e-e65ee6d11231
puts `uuidgen`
51d5348b-8fc3-4c44-a6f7-9a8588d7f08a
puts `uuidgen`
332a0fa3-7b07-41e1-9fc8-ef804a377e4e

se confrontato con uuidgemma, saprai la differenza.

irb(main):003:0> uuid.generate
=> "40cdf890-ebf5-0132-2250-20c9d088be77"
irb(main):004:0> uuid.generate
=> "4161ac40-ebf5-0132-2250-20c9d088be77"

L'ambiente di test è l'ambiente Linux e Mac OS.


2
a puts `...`sta fondamentalmente facendo una chiamata di sistema alla uuidgen(3)quale fallisce su qualsiasi altra piattaforma diversa da Linux, aggiunge quantità estreme di tempo di esecuzione, e in generale è davvero una pratica di codifica intuitiva. Perché dovresti scegliere un tale metodo?
Dwight Spencer,

1
@DwightSpencer Penso che siamo in aree diverse con scopi diversi. Quello che ti interessa non è affatto nelle mie preoccupazioni, come il tempo di esecuzione, l'ampia gamma di sistemi operativi, le migrazioni del codice. Mi interessa che il codice funzioni in Mac OS o nel flusso principale Linux e ottenga il risultato giusto di cui ho bisogno. Naturalmente, se riesci a trovare un modo in Ruby e ottenere lo stesso risultato del comando uuidgen, sono felice di usarlo. Ma fino ad ora non ne ho trovato nessuno.
BMW

1
Sia @J_ che @ simone-carletti hanno già indicato un modo migliore in questo post. Io per primo suggerirei SecureRandomche sta preformando la stessa funzione nello stesso metodo di uuidgenma a differenza uuidgendell'uso del blocco / dev / random SecureRandomusa solo la libreria di openssl prima poi scende su dev / urandom quindi infine / dev / random nei tentativi di fare generazione di randomizzazione non bloccante.
Dwight Spencer,

0

Questa è una tecnica neet che ho imparato da JavaScript:

def uuid
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[rand(36)]
    end
end

Anche se in un modo più "rubino" si potrebbe anche fare:

def uuid
    "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
        rand(16).to_s(16)
    end
end
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.