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
}