dice-hash provides a framework to generate stable hashes. It provides state-of-the-art hash functions, supports STL containers out of the box and helps you to defines stable hashes for your own structs and classes.
🔋 batteries included: dice-hash defines policies to support different hash algorithms. It comes with predefined policies for three state-of-the-art hash functions:
- XXH3
- wyhash
- "martinus", the internal hash function from robin-hood-hashing
These three, additional, general purpose hash functions are also (optionally) provided
📦 STL out of the box: dice-hash supports many common STL types already:
arithmetic types like bool, int, double, ... etc.; collections like std::unordered_map/set, std::map/set, std::vector, std::tuple, std::pair, std::optional, std::variant, std::array and; all combinations of them.
🔩 extensible: dice-hash supports you with helper functions to define hashes for your own classes. Checkout usage.
- A C++20 compatible compiler. Code was only tested on x86_64.
- If you want to use Blake2b, Blake2Xb or LtHash: libsodium (either using conan or a local system installation) (for more details scroll down to "Usage for general data hashing")
To use it with conan you need to add the repository:
conan remote add dice-group https://conan.dice-research.org/artifactory/api/conan/tentrisTo use it add dice-hash/0.4.11 to the [requires] section of your conan file.
You can now add it to your target with:
target_link_libraries(your_target
        dice-hash::dice-hash
        )#get it 
git clone https://github.com/dice-group/dice-hash.git
cd dice-hash
#build it
wget https://github.com/conan-io/cmake-conan/raw/develop2/conan_provider.cmake -O conan_provider.cmake
mkdir build
cd build
cmake -DBUILD_TESTING -DCMAKE_BUILD_TYPE=Release ..  -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=conan_provider.cmake
make -j tests_dice_hash
./test/tests_dice_hashNote: This example uses conan as dependency provider, other providers are possible. See https://cmake.org/cmake/help/latest/guide/using-dependencies/index.html#dependency-providers
You need to include a single header:
#include <dice/hash.hpp>The hash is already defined for a lot of common types. In that case you can use the DiceHash just like std::hash.
This means these hashes return size_t, if you need larger hashes skip to the section below.
dice::hash::DiceHash<int> hash;
hash(42);basicUsage is a run able example for this use-case.
If you need DiceHash to be able to work on your own types, you can specialize the dice::hash::dice_hash_overload template:
struct YourType{};
namespace dice::hash {
    template <typename Policy>
    struct dice_hash_overload<Policy, YourType> {
        static std::size_t dice_hash(YourType const& x) noexcept {
            return 42;
        }
    };
}Here is an compilable example.
If you want to combine the hash of two or more objects you can use the
hash_combine or hash_invertible_combine function.
These are part of the Policy, however they can be called via the DiceHash object.
An example can be seen here.
If your own type is a container type, there is an easier and faster way to define the hash for you.
There are the two typetraits is_ordered_container and is_unordered_container.
You just need to set these typetraits for your own type, and the hash will automatically loop over the entries and hash them.
struct YourOwnOrderedContainer{...};
namespace dice::hash {
    template<> struct is_ordered_container<YourOwnOrderedContainer> : std::true_type {};
}Now you can use DiceHash with your container.
However:
Your container needs to have begin, end and size functions.
One simple example can be found here.
If you want to use DiceHash in a different structure (like std::unordered_map), you will need to set DiceHash as the correct template parameter.
This is one example.
The hash functions mentioned in this section are enabled/disabled using the feature flag WITH_SODIUM=ON/OFF.
Enabling this flag (default behaviour) results in libsodium being required as a dependency.
If using conan, libsodium will be fetched using conan, otherwise dice-hash will look for a local system installation.
The hashes mentioned here are not meant to be used in C++ containers as they do not return size_t.
They are instead meant as general hashing functions for arbitrary data.
Blake2b - "fast secure hashing" (with output sizes from 16 bytes up to 64 bytes)
To use it you need to include
#include <dice/hash/blake2/Blake2b.hpp>For a usage examples see: examples/blake2b.cpp.
Blake2Xb is a hash function that produces hashes of arbitrary length.
To use it you need to include
#include <dice/hash/blake2/Blake2xb.hpp>For a usage examples see: examples/blake2xb.cpp.
Blake3 - one function, fast everywhere
Blake3 is an evolution of Blake2.
To use it you need to include
#include <dice/hash/blake2/Blake3.hpp>For a usage examples see: examples/blake3.cpp.
LtHash - homomorphic/multiset hashing
LtHash is a multiset/homomorphic hash function, meaning, instead of working on streams of data, it digests
individual "objects". This means you can add and remove "objects" to/from an LtHash (object by object)
as if it were a multiset and then read the hash that would result from hashing that multiset.
Small non-code example that shows the basic principle:
LtHash({apple}) + LtHash({banana}) - LtHash({peach}) + LtHash({banana}) = LtHash({apple1, banana2, peach-1})
To use it you need to include
#include <dice/hash/lthash/LtHash.hpp>For a usage example see examples/ltHash.cpp.