OptimusId
Obfuscate 32-bit numbers.
Transform your internal ids to obfuscated integers. Similar to Hashids, although around 1000x faster (see the Benchmark section below).
Elixir implementation is compatible with PHP implementation.
Getting started
Generate and store the secret
Start by generating the secret (choose large prime number that fits in 4-byte integer):
mix optimus_id.gen.secret 2078493839You'll get output similar to following:
Generated secret tuple:
{2078493839, 1968460399, 752744640}
It may be stored in env var or secret vault as following string:
2078493839-1968460399-752744640Depending on your application and approach towards security you may choose one of following approaches towards storing the newly generated secret:
use the tuple representation directly (e.g. if the secret will be hardcoded into source code or stored in database with support for Erlang terms like ETS)
store string representation yielded by
OptimusId.Secret.to_string/1and convert it back to tuple representation (e.g. if using env vars or arbitrary secret vault)
Note that OptimusId doesn't use the string version for performance reasons and since libraries are
not available in config/*.exs you'll have to convert it yourself e.g. with following code in
config/releases.exs:
secret_string = System.fetch_env!("MY_SECRET")
secret_tuple =
secret_string
|> String.split("-")
|> Enum.map(&String.to_integer/1)
|> List.to_tuple
config :my_app, :my_secret, secret_tupleFor improved security you may choose to use multiple secrets (e.g. one per API resource).
Encode and decode
Let's start by encoding:
iex> OptimusId.encode(17, {2078493839, 1968460399, 2327522479})
2963487184
Our internal identifier (17) was transformed into obfuscated identifier (2963487184) which is
safe to be made public.
In order to recover original identifier we have to call decode function:
iex> OptimusId.decode(2963487184, {2078493839, 1968460399, 2327522479})
17Benchmark
Run benchmark with:
mix run priv/benchmark/benchmark.exs
If you also add :hashids to the project deps, you'll see output like below:
OptimusId
- encode: 3979 μs
- decode: 5382 μs
Hashids
- encode: 5430765 μs
- decode: 5472152 μs