A while back I was looking for a way to generate short unique tokens to be used as authorization tokens in urls. I did some research and asked on ruby-talk. Here’s a summary of what I found.
Note that most of these algorithms can be translated to C#, Java, IronRuby/JRuby or your language and platform of choice.
My choice: Dave Bass’s rand().to_s() trick
Dave Bass proposed this which I picked up for my implementation (here for an 8-chars token):
>> rand(36**8).to_s(36)
=> "uur0cj2h"
The result can be used as an url; pretty neat. It relies on the ability of Fixnum to translate itself to a string in a given base (here we use base 36, which I rarely use!).
This can be used in an ActiveRecord model for instance:
class Customer < ActiveRecord::Base
validates_presence_of :access_token
validates_uniqueness_of :access_token
protected
def before_validation_on_create
self.access_token = rand(36**8).to_s(36) if self.new_record? and self.access_token.nil?
end
end
Jamie Macey feedback
Jamie proposed several options. First, use a substring of SHA1, which is “small enough to be usable, but still pseudo-random enough for temporary tokens to not be guessable” :
>> require 'digest'
=> []
>> Digest::SHA1.hexdigest("some-random-string")[8..16]
=> "2ebe5597f"
Another technique is to rely on ActiveSupport SecureRandom, and tweak the results a bit to get a url-friendly token. Here’s my final bit of code with this method:
>> require 'active_support'
=> []
>> ActiveSupport::SecureRandom.base64(8).gsub("/","_").gsub(/=+$/,"")
=> "AEWQyovNFo0"
Jamie’s last proposal is “not terribly robust, but functional” :
>> chars = ['A'..'Z', 'a'..'z', '0'..'9'].map{|r|r.to_a}.flatten
>> Array.new(6).map{chars[rand(chars.size)]}.join
=> "g64wdR"
Ryan Davis: let’s put more words in it
Ryan proposed something totally different:
>> words = File.read("/usr/share/dict/words").split; max = words.size
=> 234936
>> "#{words[rand(max)]}-#{words[rand(max)]}"
=> "loquat-motorial"
The idea is interesting. You’ll need to ensure your dictionary doesn’t contain insults, if your user base cares about that :)
Another option Ryan got from Eric is to use the quite unknown bubble-babble to make hash values more readable:
>> require 'digest/bubblebabble'
=> true
Digest.bubblebabble(Digest::SHA1::hexdigest("random string")[8..12])
=> "xesik-fymak-gunax"
John Mettraux’s Rufus Mnemo
rufus-mnemo has the ability to translate an integer into easy-to-remember words, based on Japanese syllabes:
>> require 'rufus/mnemo'
>> s = Rufus::Mnemo::from_integer rand(8**5)
=> "bisoshi"
Pretty neat! The generated words are “easy to the latin ears”. Take care of the meaning if your users are Japanese-speaking.
If you use UUID – be careful with Solaris zones!
If you deploy to Solaris zones, be careful about that: some other libraries I had a look at, like the very nice assaf’s uuid, are relying on macaddr, which doesn’t seem to work on Solaris Zone.
See here, here and here for solutions if you’re in trouble.
Have you got more ?
Please share using the comments system.
cheers!
The comments system is brand new - don't be afraid to comment!
- Monitoring File Changes and Getting Notified via Growl (February 14th, 2010)
- How to use Google Calendar and Rufus-Google for Basic Time Tracking (November 27th, 2009)
- Using JRuby to prototype VST plugins (November 17th, 2009)
- Introducing Learnivore.com (September 15th, 2009)
- Detecting Which Ruby Interpreter is Running (JRuby, IronRuby) (March 4th, 2009)
- How to create an empty Rails Edge application (January 28th, 2009)
- How to Freeze Gems with Rails >= 2.1 (December 23rd, 2008)
- Thoughts on IronRuby and .Net Testing (December 1st, 2008)
- How to Retrieve Delicious Tags and Number of Bookmarks for a Given Url (November 30th, 2008)
- Fixing Symbol not found _rl_filename_completion_function (November 6th, 2008)
- How to Generate a Gradient for your CSS using RMagick (October 21st, 2008)
- Analyzing Your GMail History (September 18th, 2008)
- Data Visualization with Ruby and RMagick - Where Are Those Bikes ? (March 31st, 2008)
- All-Time Classics: a Selection of Recommended Books for Software Developers (February 23rd, 2008)

