0

I am building a web site in which there is public content on pages but I don't want users to be able to guess what the next page is just by changing the id of the row that is directly in the URL.

I found out here that the way to do was to encode and decode decimal/base 36. But the problem with this method is that the id is still easily guessable, as 1 would remain 1, and 13 would be D, etc.

What is the best practice and method for using longer hash/alphanumeric strings as id? Kind of like Youtube URLs, without any possibility of collision?

Thanks for your help and advices, it's very appreciated.

Community
  • 1
  • 1
Jeff B.
  • 1,117
  • 3
  • 16
  • 40
  • you could store a pre-hashed id string as a secondary "primary" key in your table, or you use could use a reversible crypt method, e.g. aes->base64 – Marc B Feb 20 '13 at 17:24
  • Make a hashtable for your numbers + add salt. Compare them, get the original numbers. – sybear Feb 20 '13 at 17:24
  • you could create a url slug from the name of the article/page and store that along side your data in your db. This will also make transitioning from an id to a mod_rewrite seo friendly url easier. – Lawrence Cherone Feb 20 '13 at 17:26
  • @MarcB: It doesnt make alphanumeric strings, there is sometimes undesirable characters in those hashs, and it's easy to decode. – Jeff B. Feb 20 '13 at 17:27
  • @jean: `update yourtable set hash=sha1(concat(id, 'salt'))` is not undesirable and definitely not easy to decode. – Marc B Feb 20 '13 at 17:28
  • @l̕aͨŵƦȆ̴̟̟͙̞ͩ͌͝ƞCͭ̏ȇƇhƐȓ0nè: I don't have data for generating this in this part of website, I would otherwise. – Jeff B. Feb 20 '13 at 17:30
  • @Jari: I was looking for a way limiting my MySQL requests. Like I could simply decode string with PHP and then request with Int Id in MySQL. – Jeff B. Feb 20 '13 at 17:30

3 Answers3

1

You could encrypt/decrypt your IDs instead of encoding. However, it sounds like you have a specific sequence of steps (pages) that must be performed in order.

I believe a better approach for this would be to have a business class that determines whether the user is actually allowed (yet) to see the page requested. This way, you could use the IDs on the Url but rely on your code to determine acccess.

Ulises
  • 13,229
  • 5
  • 34
  • 50
1

Perhaps the best idea would be to modify the number before the hash with a simple non-linear algorithm. perhaps something like:

<?php

$id = ($_GET['id']*3)+2;

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

And then to unhash, just invert the algorithm:

<?php

$id = dase_convert($id, 36, 10);

$id = ($id-2)/3;
  • So far it's my favorite solution, but I'm trying to make sure there is no risk of collison. – Jeff B. Feb 20 '13 at 17:36
  • The only real risk is someone guessing the pattern, and losing the values between your newly generated IDs. eg: 1, becomes 5, 2 becomes 8, 3 becomes 11 –  Feb 20 '13 at 17:37
  • Is it fast to process by PHP if I convert strings like 1EAFDY (84467302)? I'd use something like `($id*1234)+2` for longer URLs... – Jeff B. Feb 20 '13 at 17:47
  • I don't know a lot about function efficiency when it comes to PHP. I actually just found this particular function after a quick [Google search](http://php.net/manual/en/function.base-convert.php), but I can't imagine it'd more more of a strain on the server than hashing it with some other algorithm (salting before MD5 or something similar). –  Feb 20 '13 at 17:50
  • Thank you. After I tested it's exactly what I needed. – Jeff B. Feb 20 '13 at 18:40
0

Implement the use of GUIDs as your identity.

GUIDs (Globally Unique Identifier) are 128-bit values, so you have a helluva lotta guessing to do if you want to catch someone's ID.

There are various tools to generate GUIDs, VS2010 has a utility to slap a GUID into plain text for you, but I am unaware as to how one would go about generating from code, as I have never needed to, only ever for one-off usage.

GUIDs are very good for Identity. :)

Phoenix
  • 41
  • 1
  • 6