2009-07-13 8 views
97

Tengo un problema que se soluciona fácilmente con Guids.Generación de guías en Ruby

En particular, para un flujo de trabajo de restablecimiento de contraseña, me gustaría enviar un token Guid al correo electrónico de un usuario y hacer que restablezcan su contraseña utilizando el token. Como las guids son únicas, esto es bastante seguro y me ahorra contraseñas de personas por correo electrónico, lo cual es arriesgado.

Me di cuenta de que hay uno Guid gem para Ruby; pero parece bastante viejo, y escribe cosas en el sistema de archivos.

¿Alguien sabe de alguna otra gema que pueda crear un identificador global único?

sé que sólo puede caer de nuevo a:

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

Pero no parece realmente como un GUID adecuado ...

+0

Usar una cadena aleatoria como esa no sería del todo correcto; ciertos bits en el UUID especifican la variante y la versión. Para un UUID aleatorio, probablemente desee la variante 2 (RFC 4122) y la versión 4, en cuyo caso 6 bits determinados deben configurarse con los valores correctos. – jtpereyda

+1

Sí @dafrazzman tiene razón. Al remontar al azar algo que "se asemeja a un UUID" no garantiza la singularidad. Si bien ningún UUID está * realmente * garantizado, la construcción de uno con números aleatorios es mucho más susceptible a las colisiones y no podría ser digno de la etiqueta "UUID". Definitivamente vaya con SecureRandom.uuid! – dooleyo

Respuesta

207

A partir de Ruby 1.9, la generación de uuid está incorporada. Use la función SecureRandom.uuid.

Por ejemplo:

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

SecureRandom.uuid genera un UUID aleatorio, por lo que no está garantizado como único. Si solo quieres una cadena aleatoria que sea probablemente única, estará bien usar esto. Sin embargo, si quiere algo que garantice que es único, necesitará usar algo que incluya la dirección MAC, la marca de tiempo y demás. –

+20

Para ahorrarle un poco de búsqueda, necesitará requerir 'securerandom' –

+8

No se garantiza que sea único, pero para la mayoría de los propósitos prácticos, es seguro asumir que es único. Ver: http://stackoverflow.com/questions/2977593/is-it-safe-to-assume-a-guid-will-always-be-unique –

20

Did nos fijamos en UUIDTools?

UUIDTools fue diseñado para ser una biblioteca simple para generar cualquiera de los varios tipos de UUID (o GUID si prefiere llamarlos así). Cumple con RFC 4122 siempre que sea posible.

+0

no notó eso. Parece que resuelve mi problema –

+0

Muy bueno - Espero que sea el truco :) –

31

How to create small, unique tokens in Ruby

>> require 'digest' 
=> [] 
>> Digest::SHA1.hexdigest("some-random-string")[8..16] 
=> "2ebe5597f" 

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

>> rand(36**8).to_s(36) 
=> "uur0cj2h" 
+2

Hay muchas soluciones geniales en esta página. – Abel

+4

En caso de que alguien quiera buscar esto. [Wayback Machine] (http://web.archive.org/web/20120925034700/http://blog.logeek.fr/2009/7/2/creating-small-unique-tokens-in-ruby) – engineerDave

14

Google obtiene la siguiente librería Ruby:

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

Además, encima en http://www.ruby-forum.com/topic/99262 dicen que puede instalar una joya (ejecutar gem uuid en la línea de comandos para instalarlo) y luego hacer

gem 'uuid' 
puts UUID.new 

en su código para ver un nuevo UUID.

(Pista: Busqué en Google para rubí GUID)

+0

thx I lo vi pero es muy viejo, solo busca algo activo, como una joya reciente? –

+2

No pasa nada con una biblioteca antigua. –

+0

¿Qué tal la uuid joya que agregué a mi respuesta? ¿O es ese a quien te refieres? –

34

Utilizamos UUIDTools y no tienen problemas con él.

+2

'uuidtools' funciona, incluso cuando el sistema no tiene una dirección MAC. 'uuid' falla en este caso. – grefab

+3

A diferencia de la gema uuid, uuidtools no conserva ningún archivo de estado. Los problemas de permisos con el archivo de estado hacen que la joya uuid sea algo incómoda para usar con múltiples usuarios. –

+0

Parece que UUID Tools ya no se mantiene. No ha habido ningún compromiso con el repositorio de Github en más de 2 años – dotnetguy

1

Durante la programación por la noche me ocurrió la siguiente solución (con sede fuera de Simone) para generar un GUID único en rieles. No estoy orgulloso de ello, pero funciona bastante bien.

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

Espero que recuerde indexar su columna guid esa noche – nurettin

1

Para crear un adecuado, MySQL, varchar 32 GUID

SecureRandom.uuid.gsub('-','').upcase 
0

Cuando solía gemas UUID que se recomiendan en esta pregunta, nadie puede generar UUID único y aleatorio. Mi respuesta es una alternativa, si tenemos gema más tarde para satisfacer la solicitud, será mejor que utilices la gema en Ruby.

Intento la mayoría de las gemas de uuid recomendadas en esta pregunta, pero nadie me satisface, necesitamos uuid único y aleatorio. Ejecuto directamente el comando del sistema uuidgen en ruby, y me gusta el resultado, y lo comparto aquí.

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 

si se compara con uuid gema, usted sabrá la diferencia.

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

Entorno de prueba es entorno Linux y Mac OS.

+1

un 'puts \' ... \ '' básicamente hace una llamada al sistema a 'uuidgen (3)' que falla en cualquier otra plataforma que no sea Linux, agrega cantidades extremas de tiempo de ejecución, y en general es realmente una práctica de codificación intuitiva. ¿Por qué elegir este método? –

+1

@DwightSpencer Creo que estamos en un área diferente con un propósito diferente. Lo que le importa no es en absoluto mi preocupación, como el tiempo de ejecución, la amplia gama de sistemas operativos, las migraciones de código. Me importa que el código pueda funcionar en Mac OS o en la transmisión principal de Linux y obtenga el resultado correcto que necesito. Por supuesto, si puedes encontrar un camino en Ruby y obtener el mismo resultado que el comando uuidgen, me complace usarlo. Pero hasta ahora, no encontré ninguno. – BMW

+0

Tanto @J_ como @ simone-carletti ya han señalado una mejor manera en esta publicación. Por mi parte, sugeriría 'SecureRandom' ya que está preformando la misma función en el mismo método que' uuidgen', pero a diferencia del uso de 'uuidgen' del bloqueador/dev/random only' SecureRandom' usa primero la biblioteca de openssl y luego la aplica a dev/urandom luego finalmente/dev/random en intentos de generación de aleatorización no bloqueante. –

2

Pequeña actualización a Simone Carletti respuesta:.

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

=> "AEWQyovNFo0"

se puede sustituir con:

SecureRandom.urlsafe_base64 (8)

Cuestiones relacionadas