Generating GUIDs in 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"
I need to generate uuid for my rails application. What are the options(gems) I have?
There are plenty of options, I recommend not to add additional dependencies and use SecureRandom
which is builtin:
SecureRandom.uuid #=> "1ca71cd6-08c4-4855-9381-2f41aeffe59c"
See other possible formats here.
Ruby On Rails: Initialize object with random GUID on .new?
you can use the after_initialize
callback, that is called every time an object of your class is instantiated.
class User < ActiveRecord::Base
after_initialize :generate_guid, unless: :guid
def generate_guid
self.guid = # your method here
end
end
you can also set this field to be a primary key in your migration:
create_table :users, primary_key: :guid do |t|
however, do you really need to create a guid every time you instantiate an object ? It seems really computationaly expensive. And as someone commented, be warned that rails sometimes behaves weirdly when you get out of common patterns and conventions...
How can I convert a GUID into a byte array in Ruby?
Your example GUID is in a Microsoft specific format. From Wikipedia:
Other systems, notably Microsoft's marshalling of UUIDs in their COM/OLE libraries, use a mixed-endian format, whereby the first three components of the UUID are little-endian, and the last two are big-endian.
So in order to get that result, we have to move the bits around a little. Specifically, we have to change the endianess of the first three components. Let's start by breaking the GUID string apart:
guid = '35918bc9-196d-40ea-9779-889d79b753f0'
parts = guid.split('-')
#=> ["35918bc9", "196d", "40ea", "9779", "889d79b753f0"]
We can convert these hex-strings to binary via:
mixed_endian = parts.pack('H* H* H* H* H*')
#=> "5\x91\x8B\xC9\x19m@\xEA\x97y\x88\x9Dy\xB7S\xF0"
Next let's swap the first three parts:
big_endian = mixed_endian.unpack('L< S< S< A*').pack('L> S> S> A*')
#=> "\xC9\x8B\x915m\x19\xEA@\x97y\x88\x9Dy\xB7S\xF0"
L
denotes a 32-bit unsigned integer (1st component)S
denotes a 16-bit unsigned integer (2nd and 3rd component)<
and>
denote little-endian and big-endian, respectivelyA*
treats the remaining bytes as an arbitrary binary string (we don't have to convert these)
If you prefer an array of bytes instead of a binary string, you'd just use:
big_endian.bytes
#=> [201, 139, 145, 53, 109, 25, 234, 64, 151, 121, 136, 157, 121, 183, 83, 240]
PS: if your actual GUID isn't Microsoft specific, you can skip the swapping part.
Generating a short UUID string using uuidtools In Rails
You don't need uuidtools for this. You can use Secure Random for this.
[1] pry(main)> require "securerandom"
=> true
[2] pry(main)> SecureRandom.hex(20)
=> "82db4d707c4c5db3ebfc349da09c991b7ca0faa1"
[3] pry(main)> SecureRandom.base64(20)
=> "CECjUqNvPBaq0o4OuPy8RvsEoCY="
Passing 4
and 5
to hex
will generate 8 and 10 character hex strings respectively.
[5] pry(main)> SecureRandom.hex(4)
=> "a937ec91"
[6] pry(main)> SecureRandom.hex(5)
=> "98605bb20a"
How to create ruby uuid from bytes?
Another way to skin a cat, simple and easy to understand:
a = [107, 97, 155, 242, 36, 52, 182, 87, 67, 223, 163, 166, 7, 175, 123, 223]
def _guid(ints, reverse=false)
hexes = ints.map { |b| b.to_s(16).rjust(2, '0') }
return hexes.reverse.join if reverse
hexes.join
end
def guid(ints)
'%s-%s-%s-%s-%s' % [
_guid(ints[0...4], true),
_guid(ints[4...6], true),
_guid(ints[6...8], true),
_guid(ints[8...10]),
_guid(ints[10..-1]),
]
end
puts guid a # => f29b616b-3424-57b6-43df-a3a607af7bdf
How to retrieve a GUID and value from a string in ruby
Here's an approach that will work - split up the target string into tokens by whitespace and equals-sign characters (tokens=str.split(/[= ]/)
) and create a Hash out of them (Hash[*tokens]
). The result is a Hash
whose keys are the token before the equals sign and the values are the ones after it:
s = 'word=0 id=891efc9a-2210-4beb-a19a-5e86b2f8a49f'
h = Hash[*s.split(/[= ]/)]
h # => {"word"=>"0", "id"=>"891efc9a-2210-4beb-a19a-5e86b2f8a49f"}
h['word'] # => "0"
h['id'] # => "891efc9a-2210-4beb-a19a-5e86b2f8a49f"
Of course, it will break if your "keys" or "values" contain equal signs or spaces but it works for your example.
Related Topics
Is There a "Do ... While" Loop in Ruby
How to Install Postgresql'S Pg Gem on Ubuntu
How to Find Which Operating System My Ruby Program Is Running On
Pg::Error: Select Distinct, Order by Expressions Must Appear in Select List
Is There an Efficient Way to Perform Hundreds of Text Substitutions in Ruby
Installing Bootstrap 3 on Rails App
How to Solve Error "Missing 'Secret_Key_Base' For 'Production' Environment" (Rails 4.1)
When to Use Symbols Instead of Strings in Ruby
How to Replace Accented Latin Characters in Ruby
Ruby Multiline Block Without Do End
How to Update Ruby Version 2.0.0 to the Latest Version in MAC Osx Yosemite
How to Create a Deep Copy of an Object in Ruby
How to Check If a Value Exists in an Array in Ruby
How to Skip the First Line of a CSV File and Make the Second Line the Header
Why Is Division in Ruby Returning an Integer Instead of Decimal Value