Some Ruby on Rails side-project hacking I’ve been doing led me to need to generate shortened URLs. The ShortURL gem is fine if you want to use TinyURL, Snurl, or some other external service to generate and manage your URLs, but in my case, I need to host the URLs so I can track usage statistics and redirect to a URL determined at request-time.
I wanted to avoid generating curse words, or any words for that matter, so I opted not to use vowels rather than try and figure out something more clever. I also had no requirement to obfuscate the sequential nature of the generated value. The result essentially converts a number to a base 54 string suitable for use as a URL parameter.
URL_CHARS = ('0'..'9').to_a + %w(b c d f g h j k l m n p q r s t v w x y z) + %w(B C D F G H J K L M N P Q R S T V W X Y Z - _)
URL_BASE = URL_CHARS.size
def generateUrl idNumber
localCount = idNumber
result = ”;
while localCount != 0
rem = localCount % URL_BASE
localCount = (localCount – rem) / URL_BASE
result = URL_CHARS[rem] + result
My usage will be to convert the numeric primary key of my model objects to this hash, so that Person #1174229 could be referenced as the short url http://app.com/p?i=7sH_
Obviously, the straightforward business of inserting this value into your table, performing lookups on it, etc is omitted and should be fairly straightforward to a seasoned developer. The function can fit almost a half-billion values into 5 characters, and doesn’t experience the stack overflow issues of some recursive implementations I found, so I think it’s pretty useful. (7 characters give you 1.3 trillion possibilities… nice!)
I can see a pretty cool plugin being built to solve this problem… maybe I’ll get around to writing short_url_fu one of these days.