Generating GUIDs in Ruby

RubyGuid

Ruby Problem Overview


I have a problem that is really easily solved with GUIDs.

In particular, for a password reset workflow, I would like to send a GUID token to a user's email and have them reset their password using the token. Since GUIDs are unique, this is pretty secure and saves me emailing people passwords, which is risky.

I noticed there is one uuid gem @ rubyforge but it looks quite old, and it writes stuff to the file system.

Does anyone know of any other gems that can create a globally unique identifier?

I know I can just fall back to:

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

But it does not really seem like a proper GUID ...

Ruby Solutions


Solution 1 - Ruby

As of Ruby 1.9, uuid generation is built-in. Use the SecureRandom.uuid function.

For example:

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

Solution 2 - Ruby

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"

Solution 3 - Ruby

Did you look at UUIDTools?

> UUIDTools was designed to be a simple library for generating any of the various types of UUIDs (or GUIDs if you prefer to call them that). It conforms to RFC 4122 whenever possible.

Solution 4 - Ruby

Google yields the following Ruby library:

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

Also, over at http://www.ruby-forum.com/topic/99262 they say you can install a gem (execute gem uuid on the command line to install it) and then do

gem 'uuid'
puts UUID.new

in your code to see a new UUID.

(Hint: I Googled for guid ruby)

Solution 5 - Ruby

To create a proper, mysql, varchar 32 GUID

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

Solution 6 - Ruby

Small update to Simone Carletti answer:

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

> => "AEWQyovNFo0"

can be replaced with:

>SecureRandom.urlsafe_base64(8)

Solution 7 - Ruby

While programming late at night I came up with the following solution (based off Simone's) for generating a unique GUID in Rails. I am not proud of it but it does work quite well.

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

Solution 8 - Ruby

This is a neet technique I learnt from JavaScript:

def uuid
	"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
		"0123456789ABCDEF"[rand(16)]
	end
end

Although in a more 'ruby way' one could also do:

def uuid
	"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
		rand(16).to_s(16)
	end
end

Solution 9 - Ruby

> When I used uuid gems recommended in this question, no one can generate unique and random UUID. My answer is a work around, if we have gem later to satisfy the request, you'd better to use gem in Ruby.

I try most recommended uuid gems in this question, but no one make me satisfied, we need unique and random uuid. I directly run system command uuidgen in ruby, and I like the result, and share here.

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

if compare with uuid gem, you will know the difference.

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

Test environment is linux and Mac OS environment.

Solution 10 - Ruby

For rails running a postgreSQL database do 2 things.

Step 1: generate a scaffold/model
rails g scaffold manager name:string --primary-key-type=uuid
Step 2: Add a line to migration file

If you rails db:migrate now, you'll get a PG::UndefinedFunction: ERROR: function gen_random_uuid() does not exist error.

So add this to the migration file

enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')

Example:

class CreateManagers < ActiveRecord::Migration[7.0]

  enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')

  def change
    create_table :managers, id: :uuid do |t|
      t.string :name
      t.timestamps
    end
  end
end

You're done!

Oh one last thing, you only nee to add enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto') to one migration file (e.g. the first time you use uuid type).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSam SaffronView Question on Stackoverflow
Solution 1 - RubyJ _View Answer on Stackoverflow
Solution 2 - RubySimone CarlettiView Answer on Stackoverflow
Solution 3 - RubyAndrew HareView Answer on Stackoverflow
Solution 4 - RubyMarc WView Answer on Stackoverflow
Solution 5 - RubyAaron HendersonView Answer on Stackoverflow
Solution 6 - RubyАлексей ЛещукView Answer on Stackoverflow
Solution 7 - RubyrobotmayView Answer on Stackoverflow
Solution 8 - RubySancarnView Answer on Stackoverflow
Solution 9 - RubyBMWView Answer on Stackoverflow
Solution 10 - RubystevecView Answer on Stackoverflow