digestpp 1.0
C++11 header-only message digest library
Loading...
Searching...
No Matches
hasher.hpp
Go to the documentation of this file.
1/*
2This code is written by kerukuro and released into public domain.
3*/
4
5#ifndef DIGESTPP_HASHER_HPP
6#define DIGESTPP_HASHER_HPP
7
8#include <string>
9#include <array>
10#include <algorithm>
11#include <vector>
12#include <iterator>
13#include <sstream>
14#include <cstring>
15#include <iomanip>
16#include <cstdint>
17
18#include "detail/traits.hpp"
21
22namespace digestpp
23{
24
36template<class HashProvider, template <class> class Mixin = mixin::null_mixin>
37class hasher : public Mixin<HashProvider>
38{
39 public:
40
49 template<typename H=HashProvider, typename std::enable_if<std::is_default_constructible<H>::value>::type* = nullptr>
51 {
52 provider.init();
53 }
54
66 template<typename H=HashProvider, typename std::enable_if<!detail::is_xof<H>::value>::type* = nullptr>
67 hasher(size_t hashsize) : provider(hashsize)
68 {
69 provider.init();
70 }
71
85 template<typename T, typename std::enable_if<detail::is_byte<T>::value>::type* = nullptr>
86 inline hasher& absorb(const T* data, size_t len)
87 {
88 provider.update(reinterpret_cast<const unsigned char*>(data), len);
89 return *this;
90 }
91
104 template<typename T, size_t N, typename std::enable_if<detail::is_byte<T>::value>::type* = nullptr>
105 inline hasher& absorb(const std::array<T, N>& arr)
106 {
107 return absorb(arr.data(), arr.size());
108 }
109
115 template<typename T,
116 typename std::enable_if<detail::is_byte<T>::value && !std::is_same<T, std::string::value_type>::value>::type* = nullptr>
117 inline hasher& absorb(const std::basic_string<T>& str)
118 {
119 if (!str.empty())
120 provider.update(reinterpret_cast<const unsigned char*>(&str[0]), str.size());
121 return *this;
122 }
123
134 inline hasher& absorb(const std::string& str)
135 {
136 if (!str.empty())
137 provider.update(reinterpret_cast<const unsigned char*>(&str[0]), str.size());
138 return *this;
139 }
140
151 template<typename T, typename std::enable_if<detail::is_byte<T>::value>::type* = nullptr>
152 inline hasher& absorb(std::basic_istream<T>& istr)
153 {
154 const int tmp_buffer_size = 65536;
155 unsigned char buffer[tmp_buffer_size];
156 while (istr.read(reinterpret_cast<T*>(buffer), sizeof(buffer)))
157 {
158 provider.update(buffer, sizeof(buffer));
159 }
160 size_t gcount = istr.gcount();
161 if (gcount)
162 {
163 provider.update(buffer, gcount);
164 }
165 return *this;
166 }
167
181 template<typename IT>
182 inline hasher& absorb(IT begin, IT end)
183 {
184 while (begin != end)
185 {
186 unsigned char byte = *begin++;
187 provider.update(&byte, 1);
188 }
189 return *this;
190 }
191
204 template<typename T, typename H=HashProvider,
205 typename std::enable_if<detail::is_byte<T>::value && detail::is_xof<H>::value>::type* = nullptr>
206 inline void squeeze(T* buf, size_t len)
207 {
208 provider.squeeze(reinterpret_cast<unsigned char*>(buf), len);
209 }
210
222 template<typename T, size_t N, typename H=HashProvider,
223 typename std::enable_if<detail::is_byte<T>::value && detail::is_xof<H>::value>::type* = nullptr>
224 inline void squeeze(T(&arr)[N])
225 {
226 squeeze(arr, N);
227 }
228
240 template<typename T, size_t N, typename H=HashProvider,
241 typename std::enable_if<detail::is_byte<T>::value && detail::is_xof<H>::value>::type* = nullptr>
242 inline void squeeze(std::array<T, N>& arr)
243 {
244 squeeze(arr.data(), arr.size());
245 }
246
269 template<typename OI, typename H=HashProvider, typename std::enable_if<detail::is_xof<H>::value>::type* = nullptr>
270 inline void squeeze(size_t len, OI it)
271 {
272 std::vector<unsigned char> hash(len);
273 provider.squeeze(&hash[0], len);
274 std::copy(hash.begin(), hash.end(), it);
275 }
276
295 template<typename H=HashProvider, typename std::enable_if<detail::is_xof<H>::value>::type* = nullptr>
296 inline std::string hexsqueeze(size_t len)
297 {
298 std::ostringstream res;
299 res << std::setfill('0') << std::hex;
300 squeeze(len, std::ostream_iterator<detail::stream_width_fixer<unsigned int, 2>>(res, ""));
301 return res.str();
302 }
303
322 template<typename T, typename H=HashProvider,
323 typename std::enable_if<detail::is_byte<T>::value && !detail::is_xof<H>::value>::type* = nullptr>
324 inline void digest(T* buf, size_t len) const
325 {
326 if (len < provider.hash_size() / 8)
327 throw std::runtime_error("Invalid buffer size");
328
329 HashProvider copy(provider);
330 copy.final(buf);
331 }
332
348 template<typename OI, typename H=HashProvider, typename std::enable_if<!detail::is_xof<H>::value>::type* = nullptr>
349 inline void digest(OI it) const
350 {
351 HashProvider copy(provider);
352 std::vector<unsigned char> hash(provider.hash_size() / 8);
353 copy.final(&hash[0]);
354 std::copy(hash.begin(), hash.end(), it);
355 }
356
371 template<typename H=HashProvider, typename std::enable_if<!detail::is_xof<H>::value>::type* = nullptr>
372 inline std::string hexdigest() const
373 {
374 std::ostringstream res;
375 res << std::setfill('0') << std::hex;
376 digest(std::ostream_iterator<detail::stream_width_fixer<unsigned int, 2>>(res, ""));
377 return res.str();
378 }
379
385 inline void reset(bool resetParameters = false)
386 {
387 if (resetParameters)
388 provider.clear();
389 provider.init();
390 }
391
392private:
393 friend Mixin<HashProvider>;
394 HashProvider provider;
395};
396
397
398} // namespace digestpp
399
400#endif // DIGESTPP_HASHER_HPP
Main class template implementing the public API for hashing.
Definition hasher.hpp:38
hasher & absorb(std::basic_istream< T > &istr)
Absorbs bytes from std::istream.
Definition hasher.hpp:152
hasher()
Default constructor.
Definition hasher.hpp:50
hasher & absorb(IT begin, IT end)
Absorbs bytes from an iterator sequence.
Definition hasher.hpp:182
std::string hexdigest() const
Return hex digest of absorbed data.
Definition hasher.hpp:372
hasher & absorb(const T *data, size_t len)
Absorbs bytes from a C-style pointer to character buffer.
Definition hasher.hpp:86
void reset(bool resetParameters=false)
Reset the hasher state to start new digest computation.
Definition hasher.hpp:385
void squeeze(T *buf, size_t len)
Squeeze bytes into user-provided preallocated buffer.
Definition hasher.hpp:206
void digest(T *buf, size_t len) const
Output binary digest into user-provided preallocated buffer.
Definition hasher.hpp:324
hasher & absorb(const std::array< T, N > &arr)
Absorbs bytes from a C++ style array to character buffer.
Definition hasher.hpp:105
void squeeze(std::array< T, N > &arr)
Squeeze bytes into user-provided preallocated buffer.
Definition hasher.hpp:242
hasher & absorb(const std::string &str)
Absorbs bytes from std::string.
Definition hasher.hpp:134
void digest(OI it) const
Write binary digest into an output iterator.
Definition hasher.hpp:349
std::string hexsqueeze(size_t len)
Squeeze bytes and return them as a hex string.
Definition hasher.hpp:296
void squeeze(size_t len, OI it)
Squeeze bytes into an output iterator.
Definition hasher.hpp:270
hasher(size_t hashsize)
Constructor with hash size parameter.
Definition hasher.hpp:67
hasher & absorb(const std::basic_string< T > &str)
Absorbs bytes from std::basic_string.
Definition hasher.hpp:117
void squeeze(T(&arr)[N])
Squeeze bytes into user-provided preallocated buffer.
Definition hasher.hpp:224
digestpp namespace
Definition ascon.hpp:14
Definition traits.hpp:17
Definition stream_width_fixer.hpp:15