SipHash v1.0.0 SipHash
Module for hashing values using the SipHash hash family.
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)
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/1
, but such usage is not
encourage. It’s better to be more explicit about what is being hashed, and
Kernel.inspect/1
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/1
is specific to Elixir,
making it annoyingly unportable.
The current implementation is just a functional hash, with more effort on the code being readable rather than optimized, and as such it’s likely to change in future (if it needs speeding up).
Options
:case
- either of:upper
or:lower
, defaults to using:upper
:c
and:d
- the number of compression rounds, default to2
and4
:padding
- whentrue
, pads left with zeroes to 16 chars as necessary
Examples
iex> SipHash.hash("0123456789ABCDEF", "hello")
"3D1974E948748CE2"
iex> SipHash.hash("0123456789ABCDEF", "this is a longer input")
"C7D6D8A1E7D359DD"
iex> SipHash.hash("0123456789ABCDEF", "hello", case: :lower)
"3d1974e948748ce2"
iex> SipHash.hash("0123456789ABCDEF", "zymotechnics", padding: :true)
"09B57037CD3F8F0C"
iex> SipHash.hash("0123456789ABCDEF", "hello", c: 4, d: 8)
"CFFB51E5125013AF"
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, [{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")
"3D1974E948748CE2"
iex> SipHash.hash_r("this is a longer input", "0123456789ABCDEF")
"C7D6D8A1E7D359DD"
iex> SipHash.hash_r("hello", "0123456789ABCDEF", case: :lower)
"3d1974e948748ce2"
iex> SipHash.hash_r("zymotechnics", "0123456789ABCDEF", padding: :true)
"09B57037CD3F8F0C"
iex> SipHash.hash_r("hello", "invalid_bytes")
** (RuntimeError) Key must be exactly 16 bytes.
iex> SipHash.hash_r(%{ "test" => "one" }, "FEDCBA9876543210")
** (FunctionClauseError) no function clause matching in SipHash.hash/3