Merge pull request #26220 from 78andyp/blurayfixes
[xbmc.git] / xbmc / utils / Digest.h
blob6452857580b7270a84f19dcbeb7912f10c33fd50
1 /*
2 * Copyright (C) 2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #pragma once
11 #include "StringUtils.h"
13 #include <iostream>
14 #include <memory>
15 #include <stdexcept>
16 #include <string>
18 #include <openssl/evp.h>
20 namespace KODI
22 namespace UTILITY
25 /**
26 * Utility class for calculating message digests/hashes, currently using OpenSSL
28 class CDigest
30 public:
31 enum class Type
33 MD5,
34 SHA1,
35 SHA256,
36 SHA512,
37 INVALID
40 /**
41 * Convert type enumeration value to lower-case string representation
43 static std::string TypeToString(Type type);
44 /**
45 * Convert digest type string representation to enumeration value
47 static Type TypeFromString(std::string const& type);
49 /**
50 * Create a digest calculation object
52 CDigest(Type type);
53 /**
54 * Update digest with data
56 * Cannot be called after \ref Finalize has been called
58 void Update(std::string const& data);
59 /**
60 * Update digest with data
62 * Cannot be called after \ref Finalize has been called
64 void Update(void const* data, std::size_t size);
65 /**
66 * Finalize and return the digest
68 * The digest object cannot be used any more after this function
69 * has been called.
71 * \return digest value as string in lower-case hexadecimal notation
73 std::string Finalize();
74 /**
75 * Finalize and return the digest
77 * The digest object cannot be used any more after this
78 * function has been called.
80 * \return digest value as binary std::string
82 std::string FinalizeRaw();
84 /**
85 * Calculate message digest
87 static std::string Calculate(Type type, std::string const& data);
88 /**
89 * Calculate message digest
91 static std::string Calculate(Type type, void const* data, std::size_t size);
93 private:
94 struct MdCtxDeleter
96 void operator()(EVP_MD_CTX* context);
99 bool m_finalized{false};
100 std::unique_ptr<EVP_MD_CTX, MdCtxDeleter> m_context;
101 EVP_MD const* m_md;
104 struct TypedDigest
106 CDigest::Type type{CDigest::Type::INVALID};
107 std::string value;
109 TypedDigest() = default;
111 TypedDigest(CDigest::Type type, std::string const& value)
112 : type(type), value(value)
115 bool Empty() const
117 return (type == CDigest::Type::INVALID || value.empty());
121 inline bool operator==(TypedDigest const& left, TypedDigest const& right)
123 if (left.type != right.type)
125 throw std::logic_error("Cannot compare digests of different type");
127 return StringUtils::EqualsNoCase(left.value, right.value);
130 inline bool operator!=(TypedDigest const& left, TypedDigest const& right)
132 return !(left == right);
135 std::ostream& operator<<(std::ostream& os, TypedDigest const& digest);