Skip to content

<xstd/misc/functional/digest.hpp>

xstd::digest

// (1)
template<class T, hash_algorithm H = boost::hash2::xxh3_128, class Flavor = boost::hash2::little_endian_flavor>
class digest;

// (2)
template<class CharT, class Traits, class Allocator, hash_algorithm H, class Flavor>
class digest<basic_string<CharT, Traits, Allocator>, H, Flavor>;

A key's digest at its algorithm's own width, from a seeded Boost.Hash2 algorithm. The class holds a prototype of H, seeded once; each call copies the prototype, appends the key and returns the algorithm's whole result.

  1. The primary template.
  2. The string specialization, taking basic_string_view<CharT, Traits>. A string, its view and a C string digest the same.

Template parameters

Parameter Meaning
T The key type. An argument converts to T before it is appended.
H The algorithm. Constrained to model hash_algorithm. Defaults to xxh3_128.
Flavor The flavor Hash2 appends with. Defaults to little_endian_flavor, so a digest is the same on every target.

Member types

Type Definition
result_type typename H::result_type

Member functions

Function Purpose
(constructor) value-initializes or seeds the prototype
operator() digests a key

(constructor)

digest() = default;                                     // (1)
constexpr explicit digest(uint64_t seed);               // (2)
constexpr digest(const unsigned char* p, size_t n);     // (3)

As for hash.

operator()

constexpr auto operator()(const T& v) const -> result_type;

The string specialization takes basic_string_view<CharT, Traits> in place of const T&.

  • Returns: h.result(), where h is a copy of the prototype after boost::hash2::hash_append(h, Flavor(), v).
  • Throws: Any exception the key's hash_append throws. It is not noexcept.

Notes

  • A digest does not model hash_algorithm: it takes a key rather than updates.
  • The digests of fixed-width keys under the default algorithm match the reference xxHash implementation's.
  • Where the digest is as wide as size_t, the hash is the digest unchanged.

Example

#include <xstd/misc/functional/digest.hpp> // digest
#include <boost/hash2/digest.hpp>          // operator<<
#include <boost/hash2/xxhash.hpp>          // xxhash_64
#include <cstdint>                         // uint64_t
#include <iostream>                        // boolalpha, cout
#include <string>                          // string
#include <string_view>                     // string_view

auto main() -> int
{
        // A digest is the same on every target and in every run, so it can be stored and compared later.
        auto const fingerprint = xstd::digest<std::string>();
        std::cout << fingerprint("Meet the new boss...") << '\n';

        // A string, its view and a C string digest the same.
        auto const text = std::string("Meet the new boss...");
        std::cout << std::boolalpha << (fingerprint(text) == fingerprint(std::string_view(text))) << '\n';

        // A seed gives another digest, at the algorithm's own width: 64 bits for xxhash_64, on a 32-bit target too.
        auto const seeded = xstd::digest<std::uint64_t, boost::hash2::xxhash_64>(42);
        std::cout << seeded(std::uint64_t{2026}) << '\n';
}

Output:

d239f1a5cc4bb36fd71b60486fda63d9
true
3081317734491188235

See also

Entity Relation
hash the same seeded prototype, folded to size_t for a container
formatter<boost::hash2::digest<N>> writes a digest as hex
hash_algorithm what H models