Enigma  3.2.0
A Simple, Reliable and Efficient Encryption Tool
HashUtils.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <Core/Core.hpp>
3 #include <array>
4 #include <files.h> // HexEncoder
5 #include <filters.h> // VectorSource, StringSource, VectorSink, StringSink
6 #include <fstream>
7 #include <hex.h> // HexEncoder
8 #include <keccak.h> // Keccak
9 #include <md2.h> // MD2
10 #include <md4.h> // MD4
11 #include <md5.h> // MD5
12 #include <sha.h> // SHA1, SHA244, SHA256, SHA384, SHA512
13 #include <shake.h> // Shake
14 #include <tiger.h> // Tiger
15 #include <whrlpool.h> // Whirlpool
16 
17 #include "FileUtils.hpp"
18 #include <Meta/Meta.hpp>
19 
21 
22 class HashUtils final {
23  ENIGMA_STATIC_CLASS(HashUtils);
24 
25  public:
26  template<typename Algo = CryptoPP::SHA256>
27  static std::array<byte, Algo::DIGESTSIZE> bytes(const byte *buffer, const std::size_t buffSize) {
28  std::array<byte, Algo::DIGESTSIZE> out{};
29  Algo algo{};
30  const CryptoPP::ArraySource vs(buffer, buffSize, true, new CryptoPP::HashFilter(algo, new CryptoPP::ArraySink(out.data(), out.size())));
31  return out;
32  }
33 
34  template<typename Algo = CryptoPP::SHA256>
35  static std::array<byte, Algo::DIGESTSIZE> bytes(const std::vector<byte>& buffer) {
36  return bytes<Algo>(buffer.data(), buffer.size());
37  }
38 
39  template<typename Algo = CryptoPP::SHA256>
40  static std::string str(const std::vector<byte>& buffer, const bool uppercase = false) {
41  std::string out{};
42  Algo algo{};
43  const CryptoPP::VectorSource vs(buffer, true, new CryptoPP::HashFilter(algo, new CryptoPP::HexEncoder(new CryptoPP::StringSink(out), uppercase)));
44  return out;
45  }
46 
47  template<typename Algo = CryptoPP::SHA256>
48  static std::array<byte, Algo::DIGESTSIZE> fileBytes(const fs::path& filename) {
49 #if OLD_IMPL
50  std::array<byte, Algo::DIGESTSIZE> out{};
51  Algo algo{};
52  std::ifstream file{filename, std::ios::binary}; // very important to open file in binary mode otherwise you will get
53  // different hash values in different OS (unix2dos dos2unix kinda crap)
54 
55  ENIGMA_ASSERT_OR_THROW(file.good(), "No such file " + filename.string());
56  const CryptoPP::FileSource fs(file,
57  true,
58  new CryptoPP::HashFilter(algo, new CryptoPP::ArraySink(out.data(), out.size())));
59  file.close();
60  return out;
61 #elif NEW_IMPL
62  Algo algo{};
63  std::array<byte, Algo::DIGESTSIZE> out{};
64  const CryptoPP::FileSource fileSource(filename.string().c_str(), true,
65  new CryptoPP::HashFilter(
66  algo,
67  new CryptoPP::ArraySink(out.data(), out.size())));
68  return out;
69 #else
70  std::array<byte, Algo::DIGESTSIZE> out{};
71  Algo algo{};
72  FileUtils::ReadChunks(filename, Meta::ENIGMA_BUFFER_DEFAULT_SIZE, [&algo](std::vector<byte>&& chunk) {
73  algo.Update(chunk.data(), chunk.size());
74  return true;
75  });
76  algo.Final(out.data());
77  return out;
78 #endif
79  }
80 
81  template<typename Algo = CryptoPP::SHA256>
82  static std::string fileStr(const fs::path& filename, const bool uppercase = false) {
83 #if OLD_IMPL
84  std::string out{};
85  std::ifstream file{filename, std::ios::binary}; // very important to open file in binary mode otherwise you will get
86  // different hash values in different OS (unix2dos dos2unix kinda crap)
87  ENIGMA_ASSERT_OR_THROW(file.good(), "No such file " + filename.string());
88  const CryptoPP::FileSource fs(file, true, new CryptoPP::HashFilter(Algo(), new CryptoPP::HexEncoder(new CryptoPP::StringSink(out), uppercase)));
89  file.close();
90  return out;
91 #elif NEW_IMPL
92  Algo algo{};
93  std::string out{};
94  ENIGMA_ASSERT_OR_THROW(fs::is_regular_file(filename), "No such file " + filename.string());
95  const CryptoPP::FileSource fileSource(filename.string().c_str(), true,
96  new CryptoPP::HashFilter(
97  algo,
98  new CryptoPP::HexEncoder(
99  new CryptoPP::StringSink(out),
100  uppercase)));
101  return out;
102 #else
103  return stringify<Algo>(fileBytes<Algo>(filename), uppercase);
104 #endif
105  }
106 
107  template<typename Algo = CryptoPP::SHA256>
108  static std::string stringify(const std::array<byte, Algo::DIGESTSIZE>& hash, const bool uppercase = false) {
109  std::ostringstream out{};
110  if (uppercase)
111  out << std::uppercase;
112  for (const byte digest : hash) {
113  out << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(digest);
114  }
115  return out.str();
116  }
117 };
118 
#define NS_ENIGMA_BEGIN
Enable/Disable Assertions.
Definition: Macros.hpp:13
#define NS_ENIGMA_END
Definition: Macros.hpp:14
#define ENIGMA_ASSERT_OR_THROW(x, msg)
Definition: Macros.hpp:41
static void ReadChunks(const fs::path &filename, const std::size_t max_chunk_size, const std::function< bool(std::vector< byte > &&)> &callback)
Definition: FileUtils.hpp:104
static std::array< byte, Algo::DIGESTSIZE > fileBytes(const fs::path &filename)
Definition: HashUtils.hpp:48
static std::string stringify(const std::array< byte, Algo::DIGESTSIZE > &hash, const bool uppercase=false)
Definition: HashUtils.hpp:108
static std::array< byte, Algo::DIGESTSIZE > bytes(const std::vector< byte > &buffer)
Definition: HashUtils.hpp:35
static std::array< byte, Algo::DIGESTSIZE > bytes(const byte *buffer, const std::size_t buffSize)
Definition: HashUtils.hpp:27
static std::string str(const std::vector< byte > &buffer, const bool uppercase=false)
Definition: HashUtils.hpp:40
static std::string fileStr(const fs::path &filename, const bool uppercase=false)
Definition: HashUtils.hpp:82
static constexpr const size_type ENIGMA_BUFFER_DEFAULT_SIZE
Definition: Meta.hpp:27