SipHash v2.1.1 SipHash
Module for hashing values using the SipHash hash family.
This module makes use of NIFs for better performance and throughput, but this
can be disabled by setting the HASH_IMPL
environment variable to embedded
.
This is controlled via the environment rather than a specific function arg as
the NIFs are automatically loaded during the start of the application. Please
note that the use of NIFs brings a significant performance improvement, and so
you should only disable them with good reason.
Due to the use of NIFs, please only use the public SipHash
functions. Do not
rely on the behaviour of any submodules, as incorrect use of native functions
can result in crashes in your application.
Summary
Functions
Based on the algorithm as described in https://131002.net/siphash/siphash.pdf,
and therefore requires a key alongside the input to use as a seed. This key
is required to be 16 bytes, and is measured by Kernel.byte_size/1
. An error
will be raised if this is not the case. The default implementation is a 2-4
hash, but this can be controlled through the options provided
Wrapper around SipHash.hash/3
to rotate the arguments, allowing for more
convenient usage when creating a pipeline (you can rotate key/input as needed)
Types
s :: {number, number, number, number}
Functions
Specs
hash(binary, binary, [{atom, atom}]) :: binary
Based on the algorithm as described in https://131002.net/siphash/siphash.pdf,
and therefore requires a key alongside the input to use as a seed. This key
is required to be 16 bytes, and is measured by Kernel.byte_size/1
. An error
will be raised if this is not the case. The default implementation is a 2-4
hash, but this can be controlled through the options provided.
Your input must be a binary. It’s possible to add a catch-all to SipHash.hash/3
which simply wraps the input in Kernel.inspect/2
, but such usage is not
encourage. It’s better to be more explicit about what is being hashed, and
Kernel.inspect/2
does not always perform the fastest available conversion
(for example, using Poison to encode Maps is far faster, whilst also being more
reliable). In addition, the output of Kernel.inspect/2
is specific to Elixir,
making it annoyingly unportable.
By default, all values are returned as numbers (i.e. the result of the hash),
but you can set :hex
to true as an option to get a hex string output. The
reason for this is that converting to hex takes an extra couple of µs, and the
default is intended to be the optimal use case. Please note that any of the
options related to hex string formatting will be ignored if :hex
is not set
to true (e.g. :case
).
Options
:case
- either of:upper
or:lower
, defaults to using:upper
:c
and:d
- the number of compression rounds, default to2
and4
:hex
- whentrue
returns the output as a hex string
Examples
iex> SipHash.hash("0123456789ABCDEF", "hello")
4402678656023170274
iex> SipHash.hash("0123456789ABCDEF", "hello", hex: true)
"3D1974E948748CE2"
iex> SipHash.hash("0123456789ABCDEF", "abcdefgh", hex: true)
"1AE57886F899E65F"
iex> SipHash.hash("0123456789ABCDEF", "my long strings", hex: true)
"1323400B0804036D"
iex> SipHash.hash("0123456789ABCDEF", "hello", hex: true, case: :lower)
"3d1974e948748ce2"
iex> SipHash.hash("0123456789ABCDEF", "hello", c: 4, d: 8)
14986662229302055855
iex> SipHash.hash("invalid_bytes", "hello")
** (RuntimeError) Key must be exactly 16 bytes.
iex> SipHash.hash("FEDCBA9876543210", %{ "test" => "one" })
** (FunctionClauseError) no function clause matching in SipHash.hash/3
Specs
hash_r(binary, binary | s, [{atom, atom}]) :: binary
Wrapper around SipHash.hash/3
to rotate the arguments, allowing for more
convenient usage when creating a pipeline (you can rotate key/input as needed).
Examples
iex> SipHash.hash_r("hello", "0123456789ABCDEF")
4402678656023170274