Skip to content

Add short alphanumeric public_id from integer#15

Merged
andyatkinson merged 1 commit into
mainfrom
chore/add-short-public-id-example
May 20, 2025
Merged

Add short alphanumeric public_id from integer#15
andyatkinson merged 1 commit into
mainfrom
chore/add-short-public-id-example

Conversation

@andyatkinson
Copy link
Copy Markdown
Owner

@andyatkinson andyatkinson commented May 8, 2025

Wanted the following properties:

  • source column is an integer (4 bytes)
  • Fixed size output for public_id, 5 characters of length, regardless of length of integer
  • public_id is a text (not char(5) per PostgreSQL "don't do this"), 1 byte per char, so 5 bytes for the chars
  • obfuscated, non-incrementing, not easily "guessable". Although, not intended to be a "secure" solution.
  • The public_id can be reversed into the original integer value
  • Only PL/PgSQL functions, Postgres data types, unique, not null, and check constraints, no extensions needed
  • Implementation is not math-heavy. It uses some bits conversion. Converts to bits. Inverts bits (XOR).

This seems to fit the bill and has these functions:

  • obfuscate_id(id INTEGER)
  • to_base62_fixed(val BIGINT, width INT DEFAULT 5)
  • deobfuscate_id(public_id TEXT)
  • from_base62_fixed(str TEXT)

For 5 char values, we could do up to ~1 billion values

For 6 char values, we could do up to ~56 billion values

@andyatkinson andyatkinson force-pushed the chore/add-short-public-id-example branch from 927311a to 328f4e2 Compare May 8, 2025 17:13
@andyatkinson
Copy link
Copy Markdown
Owner Author

Updates needed:

  • Don't use char(5) use text
  • Could add a CHECK constraint that validates the length of the input (although it's from an internal function, so maybe overkill)

Source: https://wiki.postgresql.org/wiki/Don't_Do_This

Wanted the following properties:
- source column is a integer (4 bytes)
- public_id is a text (not char(5)), 1 byte per char
- obfuscated enough so next value is not "guessable", pseudo random
- reversible
- Only PL/PgSQL functions, no extensions needed
- Implementation is not math-heavy

This seems to fit the bill and has these functions:
- obfuscate_id(id INTEGER)
- to_base62_fixed(val BIGINT, width INT DEFAULT 5)

- from_base62_fixed(str TEXT)
- deobfuscate_id(public_id CHAR(5))

For 5 chars we could do up to ~1 billion values

For 6 chars we could do up to around 56 billion values
@andyatkinson andyatkinson force-pushed the chore/add-short-public-id-example branch from 4a8fe8b to 7f2e831 Compare May 19, 2025 16:25
@andyatkinson andyatkinson merged commit 4b7cbb0 into main May 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant