Trevor
Trevor

Reputation: 2457

Randomly generated public unique ids

Currently I'm generating unique ids for rows in my database using int and auto_increment. These ids are public facing so in the url you can see something like this https://example.com/path/1 or https://example.com/path/2

After talking with another engineer they've advised me that I should use randomly generated ids so that they're not guessable.

How can I generate a unique ID & without doing a forloop on the database each time to make sure it's unique? e.g. take stripe for example. All of their ids are price_sdfgsdfg or prod_iisdfgsdfg. Whats the best way to generate unique ids for rows like these?

Upvotes: 0

Views: 843

Answers (1)

sickcodes
sickcodes

Reputation: 36

Without knowing which language or database you're using, the simplest way is using uuids.

To prevent downloading all existing database unique keys, and then for looping over them all, simply just try to INSERT INTO whichever table you are using.

If the result fails (e.g. Exception), then the row is taken, continue.

If the result passes, break loop.

This only works when you have a column which is NOT NULL, and UNIQUE.

That's how I "know" without looping over the whole database of IDs, or downloading them into local memory, etc.

Using auto_increment wont lead to duplicates because when a SQL or no-SQL table is in use, it will be locked and given to the next available number in the queue, which is the beauty of databases.

SQL example (mySQL, SQLite, mariadb):

CREATE TABLE `my_db`.`my_table` ( `unique_id` INT NOT NULL , UNIQUE (`unique_id`)) ENGINE = InnoDB;`

Insert a unique_id

INSERT INTO `test` (`unique_id`) VALUES ('999999999');

Great, we have a row

INSERT INTO `test` (`unique_id`) VALUES ('999999999');

If not, then retry:

Error:

#1062 - Duplicate entry '999999999' for key 'unique_id'

If these are public URLs, and the content is sensitive, then I definitely do not recommend int's as someone can trivially guess 1 through 99999999... etc.

In any language, have a look at /dev/urandom.

In shell/bash scripts, I might use uuidgen: 9dccd646-043e-4984-9126-3060b4ced180

In Python, I'll use pandas:

df.set_index(pd.util.hash_pandas_object(df, encoding='utf8'), drop=True, inplace=True)
df.index.rename('hash', inplace=True)

Lastly, UUID's aren't perfect: they are only a-f 0-9 all lowercase, but they are easy to generate: every language has one.

In JavaScript you may want to check out some secure Open Source apps, for example, Jitsi: https://github.com/jitsi/js-utils/blob/master/random/roomNameGenerator.js where they conjugate word:

E.g. Satisfied-Global-Architectural-Bitter

Upvotes: 2

Related Questions