1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/*
* Copyright (C) 2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#pragma once
#include "StringUtils.h"
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <gcrypt.h>
namespace KODI
{
namespace UTILITY
{
/**
* Utility class for calculating message digests/hashes
*/
class CDigest
{
public:
enum class Type
{
MD5,
SHA1,
SHA256,
SHA512,
INVALID
};
/**
* Convert type enumeration value to lower-case string representation
*/
static std::string TypeToString(Type type);
/**
* Convert digest type string representation to enumeration value
*/
static Type TypeFromString(std::string const& type);
/**
* Create a digest calculation object
*/
CDigest(Type type);
/**
* Update digest with data
*
* Cannot be called after \ref Finalize has been called
*/
void Update(std::string const& data);
/**
* Update digest with data
*
* Cannot be called after \ref Finalize has been called
*/
void Update(void const* data, std::size_t size);
/**
* Finalize and return the digest
*
* The digest object cannot be used any more after this function
* has been called.
*
* \return digest value as string in lower-case hexadecimal notation
*/
std::string Finalize();
/**
* Finalize and return the digest
*
* The digest object cannot be used any more after this
* function has been called.
*
* \return digest value as binary std::string
*/
std::string FinalizeRaw();
/**
* Calculate message digest
*/
static std::string Calculate(Type type, std::string const& data);
/**
* Calculate message digest
*/
static std::string Calculate(Type type, void const* data, std::size_t size);
private:
struct MdCtxDeleter
{
void operator()(gcry_md_hd_t context);
};
bool m_finalized{false};
std::unique_ptr<struct gcry_md_handle, MdCtxDeleter> m_context;
int const m_md;
};
struct TypedDigest
{
CDigest::Type type{CDigest::Type::INVALID};
std::string value;
TypedDigest() = default;
TypedDigest(CDigest::Type type, std::string const& value)
: type(type), value(value)
{}
bool Empty() const
{
return (type == CDigest::Type::INVALID || value.empty());
}
};
inline bool operator==(TypedDigest const& left, TypedDigest const& right)
{
if (left.type != right.type)
{
throw std::logic_error("Cannot compare digests of different type");
}
return StringUtils::EqualsNoCase(left.value, right.value);
}
inline bool operator!=(TypedDigest const& left, TypedDigest const& right)
{
return !(left == right);
}
std::ostream& operator<<(std::ostream& os, TypedDigest const& digest);
}
}
|