Forum: Ruby Options to generate small, kind of unique, human-readable tokens (like "V0cM9tnV") ?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
91eb330fb36d1e03c856574dfb77d2bc?d=identicon&s=25 Thibaut Barrère (thbar)
on 2008-12-29 10:45
(Received via mailing list)
Hi,

I'm pretty sure there is a number of options to achieve this, so I'm
asking here. I often need to generate small unique tokens (like for
invitation codes or unimportant authentication token).

In the past I've been using Digest::SHA1.hexdigest(some string) which
gives us something like "d2b7882fa08bb6de8dca62f16298683bfe4f0738".
It's not very user friendly though, and definitely not small.

More recently I've been using ActiveSupport::SecureRandom.base64(6)
which generates "Xst7JGF6" or "zXxWY/Y/", but sometimes it contains
non-url friendly characters like "/".

What do you use ? Is there a specific gem to achieve this in a robust
fashion (= making collisions unlikely, and specify the characters to
be used, like mixture of numbers and characters for instance ?)

cheers and thanks for your input,

Thibaut
5c2285f675ad99d67216b8d4f547ac8a?d=identicon&s=25 Jamie Macey (Guest)
on 2008-12-29 13:20
(Received via mailing list)
On Dec 29, 4:44 am, Thibaut Barrère <thibaut.barr...@gmail.com> wrote:
> Hi,
>
> I'm pretty sure there is a number of options to achieve this, so I'm
> asking here. I often need to generate small unique tokens (like for
> invitation codes or unimportant authentication token).
>
> In the past I've been using Digest::SHA1.hexdigest(some string) which
> gives us something like "d2b7882fa08bb6de8dca62f16298683bfe4f0738".
> It's not very user friendly though, and definitely not small.

I've mostly just used a substring on SHA1 - hexdigest[8...16] is small
enough to be usable, but still pseudo-random enough for temporary
tokens to not be guessable.

> More recently I've been using ActiveSupport::SecureRandom.base64(6)
> which generates "Xst7JGF6" or "zXxWY/Y/", but sometimes it contains
> non-url friendly characters like "/".

Base64 is A-Za-z0-9/-.  Gsub / for _ and you're pretty url friendly.

> What do you use ? Is there a specific gem to achieve this in a robust
> fashion (= making collisions unlikely, and specify the characters to
> be used, like mixture of numbers and characters for instance ?)

Lastly, 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)]}
5a837592409354297424994e8d62f722?d=identicon&s=25 Ryan Davis (Guest)
on 2008-12-30 01:51
(Received via mailing list)
On Dec 29, 2008, at 01:44 , Thibaut Barrère wrote:

> In the past I've been using Digest::SHA1.hexdigest(some string) which
> gives us something like "d2b7882fa08bb6de8dca62f16298683bfe4f0738".
> It's not very user friendly though, and definitely not small.

I personally think the following is really cute:

> words = File.read("/usr/share/dict/words").split
> max = words.size
> puts "#{words[rand(max)]}-#{words[rand(max)]}"

and can generate 55194924096 different very readable combinations.
I'll leave it to you to actually make them unique rather than random
picks.

Eric pointed me to "bubble babble" which ships in digest and makes the
hash values more readable. It converts your "Xst7JGF6" into "xikal-
fytif-ladog-locef-kixox".

> require 'digest/bubblebabble'

> puts Digest.bubblebabble("Xst7JGF6")

I had no idea that existed... pretty neat.
F9c5973e7d1eb451754426dfe955fb59?d=identicon&s=25 John Mettraux (Guest)
on 2008-12-30 02:08
(Received via mailing list)
On Mon, Dec 29, 2008 at 6:44 PM, Thibaut Barrère
<thibaut.barrere@gmail.com> wrote:
> Hi,
>
> I'm pretty sure there is a number of options to achieve this, so I'm
> asking here. I often need to generate small unique tokens (like for
> invitation codes or unimportant authentication token).
>
> In the past I've been using Digest::SHA1.hexdigest(some string) which
> gives us something like "d2b7882fa08bb6de8dca62f16298683bfe4f0738".
> It's not very user friendly though, and definitely not small.

Hi Thibaut,

I have this rufus-mnemo that turns integers into "user friendly"
strings.

http://github.com/jmettraux/rufus-mnemo


After a "sudo gem install rufus-mnemo"

you can do things like

---8<---
require 'rubygems'
require 'rufus/mnemo'

s = Rufus::Mnemo::from_integer(125704)

puts s
      # => 'karasu'
--->8---

Not exactly what you want, but could be funny. It's using a restricted
syllabary (the Japanese one) to turn integers into words (and back).

As twittered, it has the potential to generate insulting words. The
generated syllables sequences are quite easy to the latin ears though.


Best regards, meilleurs voeux pour 2009,
9d751d4cd704a4efe3a335c77c4487a3?d=identicon&s=25 Dave Bass (dogsbody)
on 2008-12-30 12:04
Generate a suitable random (or otherwise) integer and express in base
36:

  puts rand(36**6).to_s(36)

Dave
91eb330fb36d1e03c856574dfb77d2bc?d=identicon&s=25 Thibaut Barrère (thbar)
on 2009-01-02 09:12
(Received via mailing list)
Hey guys,

just want to say thank you all for the feedback and these options.
I'll gather these into a blog post later today, I think it's worth
sharing.

Thanks again!

Thibaut
This topic is locked and can not be replied to.