1

Let's say I'm building a Facebook clone in Rails

Currently my routes are pretty standard, like

/group/1/post/3

I'd love to make some synthetic ID's using the same numbering scheme that sites like Facebook use. There seem to be two general types of routes

# Only numbers
/group/10101830214008379/post/159476674458072

# Hash / Hex
/group/da295c4b/post/815fe818

Outside of aesthetics -

  1. What are some advantages/disadvantages to using either approach?
  2. Is there a good industry standard or best practice for generating synthetic ids for concepts like users, groups, posts, etc..
  3. What's the best way in Ruby/Rails to generate each of these IDs? I know of SecureRandom.hex but that seems to generate a long hash.

Thanks!

user2490003
  • 7,930
  • 12
  • 59
  • 115
  • 1
    I don't know Ruby, but I use the `crc32` hash extensively for unique IDs of various kinds of objects. Converted to hex, it gives an 8-character hashcode just like your hex codes above. It's in the [zlib module](http://stackoverflow.com/questions/4273281/how-to-calculate-32-bit-crc-in-ruby-on-rails) for Ruby. – Juan Tomas Aug 03 '16 at 19:19

2 Answers2

1
  1. What are some advantages/disadvantages to using either approach?

Using sequential numbers

Advantages: Easy to implement

Disadvantages: Possible vector for attack. See this video for a high-level overview.

Using random numbers

Advantages: Solves the problems outlined in the video re: sequential record attacks

Disadvantages: Since there's only 10 bits of entropy, ID's would have to be much longer if your app grows.

Base 64 (use this instead of hex)

Advantages: 64 bits of entropy means an ID 5 chars long would have 64^5 possible permutations. This allows for comparatively much shorter URLs. Use SecureRandom.urlsafe_base64 for this.

Disadvantages: None, really.

  1. Is there a good industry standard or best practice for generating synthetic ids for concepts like users, groups, posts, etc..

To my knowledge, no. Anything sufficiently random and of sufficient length should be fine. Within your model, you'd want to check if an ID is taken first so you don't have duplicates, but outside of that there's little to worry about.

  1. What's the best way in Ruby/Rails to generate each of these IDs? I know of SecureRandom.hex but that seems to generate a long hash.

Like I said above, I recommend using SecureRandom.urlsafe_base64

Kieran E
  • 3,459
  • 2
  • 14
  • 36
  • I noticed that `urlsafe_base64` generates something like `rkwyKkspOPgc901UP-xmtA`, which is still pretty long for a URL. Is it good practice to maybe just take the first 5 characters? That's still 64^5 (over 1 billion) combinations as you mentioned, and my database will like never exceed 100,000 records. I just didn't know if the algorithm for some reason produced these in a pattern that made the first few characters repetitive or unfit to use in a unique id scheme – user2490003 Aug 05 '16 at 06:00
  • 1
    It's fine practice to only take the first x characters. Just make sure you have a model method to ensure there's no collisions – Kieran E Aug 05 '16 at 06:02
1

What are some advantages/disadvantages to using either approach?

I think that the main advantage is that you can generate a new entity (e.g. a post) without having to rely on a sequential id generation (from the database). This is especially useful for highly concurrent or distributed systems, where you want to be able to create new entries without having to a) do the creation in a sequence or b) without running into conflicts.

Is there a good industry standard or best practice for generating synthetic ids for concepts like users, groups, posts, etc..

UUID is one widely used standard for this.

What's the best way in Ruby/Rails to generate each of these IDs? I know of SecureRandom.hex but that seems to generate a long hash.

SecureRandom.uuid

As a more human friendly and nicer alternative to uuids you could use SecureRandom.urlsafe_base64, which has a higher probability to generate non-unique values though.

koffeinfrei
  • 1,905
  • 13
  • 19