Puid (puid v1.1.2)
Define modules for the efficient generation of cryptographically strong probably unique identifiers (<strong>puid</strong>s, aka random strings) of specified entropy from various character sets
Examples
The simplest usage of Puid
requires no options. The library adds a generate/0
function for
generating puids:
iex> defmodule(Id, do: use(Puid))
iex> Id.generate()
"p3CYi24M8tJNmroTLogO3b"
By default, Puid
modules generate puids with at least 128 bits of entropy, making the
puids suitable replacements for uuids.
Character Set
The default character set for Puid
modules is the Base64 URL and file system safe character set
specified in RFC 3548. Any of the pre-defined
character sets from Puid.CharSet
can easily be specified using the charset
option:
iex> defmodule(HexId, do: use(Puid, charset: :hex))
iex> HexId.generate()
"a60dec6d0b71355aa9579bb46c001700"
Custom Characters
Any sequence of unique, printable characters can be used to generate puids.
iex> defmodule(DingoSkyId, do: use(Puid, chars: "dingosky"))
iex> DingoSkyId.generate()
"yoisknoydoknkoikgoknynkinoknkygdiikoosksyni"
iex> defmodule(UnicodeId, do: use(Puid, chars: "ŮήιƈŏδεĊħąŕαсτəř"))
iex> UnicodeId.generate()
"αήήδħƈĊŕąąιŏήąŕħƈδəəήιττδδŕąĊδŕι"
Specific Entropy
Bits
The bits
option can be used to specify desired entropy bits.
iex> defmodule Password, do: use Puid, bits: 96, charset: :printable_ascii
iex> Password.generate()
"0&pu=w+T#~o)N=E"
Since the total entropy bits of a puid must be a multiple of the entropy bits per character
used, the actual puid bits
will be equal to or greater than specified. In the example above,
the entropy bits of a Password
generated puid is actually 98.32.
Total and Risk
The amount of entropy can be intuitively specified through the total
and risk
options. For
example, to generate a total
of 10 million puids with a 1 in a quadrillion risk
of repeat
using :safe32
characters:
iex> defmodule(Safe32Id, do: use(Puid, total: 1.0e7, risk: 1.0e15, charset: :safe32))
iex> Safe32Id.generate()
"hjM7md2R9j8D7PNTjBPB"
The actual Safe32Id
puid entropy bits is 100.
Custom Randomness
Puid
generates puids using bytes from the function specified with the rand_bytes
option. If rand_bytes
is not specified, Puid
defaults to :crypto.strong_rand_bytes/1
.
iex> defmodule(MyRandBytesId, do: use(Puid, bits: 96, charset: :safe32, rand_bytes: &MyRand.bytes/1))
iex> MyRandBytesId.generate()
"G2jrmPr3mQPBt2gGB3T4"
The MyRand.bytes/1
function must be of the form (non_neg_integer) -> binary()
Module Functions
Puid
adds the following 2 functions to each created module:
Function | Description |
---|---|
generate/0 | function for generating a puid |
info/0 | Puid.Info struct of module information |
The Puid.Info
struct has the following fields:
Field | Description |
---|---|
chars | source character set |
charset | pre-defined Puid.Charset or :custom |
entropy_bits | entropy bits for generated puids |
entropy_bits_per_char | entropy bits per character for generated puids |
ere | puid entropy string representation efficiency |
length | puid string length |
rand_bytes | entropy source function |
iex> defmodule(AlphanumId, do: use(Puid, total: 10e06, risk: 1.0e15, charset: :alphanum))
iex> AlphanumId.info()
%Puid.Info{
chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
charset: :alphanum,
entropy_bits: 107.18,
entropy_bits_per_char: 5.95,
ere: 0.74,
length: 18,
rand_bytes: &:crypto.strong_rand_bytes/1
}