Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate unguessable "tiny url" based on an id?

I'm interested in creating tiny url like links. My idea was to simply store an incrementing identifier for every long url posted and then convert this id to it's base 36 variant, like the following in PHP:

$tinyurl = base_convert($id, 10, 36)

The problem here is that the result is guessable, while it has to be hard to guess what the next url is going to be, while still being short (tiny). Eg. atm if my last tinyurl was a1, the next one will be a2. This is a bad thing for me.

So, how would I make sure that the resulting tiny url is not as guessable but still short?

like image 263
Tom Avatar asked Aug 06 '10 21:08

Tom


4 Answers

What you are asking for is a balance between reduction of information (URLs to their indexes in your database), and artificial increase of information (to create holes in your sequence).

You have to decide how important both is for you. Another question is whether you just do not want sequential URLs to be guessable, or have them sufficiently random to make guessing any valid URL difficult.

Basically, you want to declare n out of N valid ids. Choose N smaller to make the URLs shorter, and make n smaller to generate URLs that are difficult to guess. Make n and N larger to generate more URLs when the shorter ones are taken.

To assign the ids, you can just take any kind of random generator or hash function and cap this to your target range N. If you detect a collision, choose the next random value. If you have reached a count of n unique ids, you must increase the range of your ID set (n and N).

like image 131
relet Avatar answered Nov 05 '22 20:11

relet


I would simply crc32 url

$url = 'http://www.google.com';
$tinyurl = hash('crc32', $url ); // db85f073

cons: constant 8 character long identifier

like image 31
dev-null-dweller Avatar answered Nov 05 '22 22:11

dev-null-dweller


This is really cheap, but if the user doesn't know it's happening then it's not as guessable, but prefix and postfix the actual id with 2 or 3 random numbers/letters.

If I saw 9d2a1me3 I wouldn't guess that dm2a2dq2 was the next in the series.

like image 4
BarrettJ Avatar answered Nov 05 '22 20:11

BarrettJ


Try Xor'ing the $id with some value, e.g. $id ^ 46418 - and to convert back to your original id you just perform the same Xor again i.e. $mungedId ^ 46418. Stack this together with your base_convert and perhaps some swapping of chars in the resultant string and it'll get quite tricky to guess a URL.

like image 3
Will A Avatar answered Nov 05 '22 20:11

Will A