Chapter 71. Message digests/hashes

x::gcrypt::md provides access to message digest or hash algorithms, such as MD5. Methods and functions that use message digests generally message digests specified by their Libgcrypt identifiers, like GCRY_MD_MD5 or by name, like md5.

#include <x/gcrypt/md.H>
#include <x/join.H>

std::set<std::string> algos;

x::gcrypt::md::base::enumerate(algos);

std::cout << join(algos, ", ") << std::endl;

enumerate() returns the names of all message digest algorithms implemented in Libgcrypt. The name() and number() functions convert message digest names to their assigned identifiers.

auto md=x::gcrypt::md::create("md5");

md->write(&buffer[0], buffer.size());

std::vector<unsigned char> digest;

md->digest(digest);

x::gcrypt::md's methods are generally equivalent to their gcry_md namesakes in Libgcrypt. The notable differences are:

An overloaded digest() returns the digest in a constructed reference-counted vector:

#include <x/vector.H>

x::vector<unsigned char> digest=md->digest();

hexdigest() converts the raw, binary, digest into a hexadecimal string, using lowercase letters:

#include <x/vector.H>

std::string h=md->hexdigest();

A more C++-ish way to calculate a digest is by using iterators.

x::gcrypt::md::base::iterator md5("md5");

*md5++='a';
*md5++='b';
*md5++='c';

auto digest=md5.digest();

std::string hexdigest=md5.hexdigest();

x::gcrypt::md::base::iterator is an output iterator. Iterating over an octet stream feeds it as the input for the message digest hash.

std::vector<char> container;

// ...

auto digest=std::copy(container.begin(), container.end(),
    x::gcrypt::md::base::iterator("md5")).digest();

This example calculates an MD5 digest for a container, in one shot.