Drop-Dead Simple Token Generation -- Fixnum#to_s
For Inspectinator, I needed a lightweight token generator to allow people to share their results. I found a great solution, and learned a cool ruby trick, too.
The trick is in Fixnum (and Bignum), #to_s takes an optional argument: a number in (2..36). That number is the base it will print the number in (default is 10).
So, for instance (from the ruby docs), to convert a number to binary:
12345654321.to_s(
2)
#=> “1011011111110110111011110000110001”
For my token, I went with an 8-character, base 36 number, which gives me almost 3 trillion possible values (should be plenty). To get the 8 characters, I use rand(36**8). I don’t do any checking on the length, so 8 is actually the max length (and 1 is the min). In practice, though, the vast majority of tokens will be the target length. On my system, I generated 10,000,000 tokens, and 9,722,373 were 8 characters. I chose to accept that as “close enough” because 1) it doesn’t really matter to me if tokens are shorter, and 2) I think the simplicity and elegance of this solution is worth a little uncertainty.
Then, (since I’m using active record), it’s just a matter of adding a before_create to set it up:
def
set_token
t =
nil
begin
t = rand(
36**
8).to_s(
end
while
InspectString.find_by_token(t)
self.token = t
end