A toolkit for working with phylogenetic data.
v0.19.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
md5.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_TOOLS_MD5_H_
2 #define GENESIS_UTILS_TOOLS_MD5_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2018 Lucas Czech and HITS gGmbH
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lucas.czech@h-its.org>
23  Exelixis Lab, Heidelberg Institute for Theoretical Studies
24  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
25 */
26 
34 #include <array>
35 #include <cstdint>
36 #include <iosfwd>
37 #include <string>
38 
39 namespace genesis {
40 namespace utils {
41 
42 // ================================================================================================
43 // MD5
44 // ================================================================================================
45 
82 class MD5
83 {
84 public:
85 
86  // -------------------------------------------------------------------------
87  // Typedefs and Constants
88  // -------------------------------------------------------------------------
89 
90  using size_type = uint32_t;
91 
92  static const size_t BlockSize = 64;
93 
101  using DigestType = std::array< uint8_t, 16 >;
102 
103  // -------------------------------------------------------------------------
104  // Constructors and Rule of Five
105  // -------------------------------------------------------------------------
106 
107  MD5();
108  ~MD5() = default;
109 
110  MD5( MD5 const& ) = default;
111  MD5( MD5&& ) = default;
112 
113  MD5& operator= ( MD5 const& ) = default;
114  MD5& operator= ( MD5&& ) = default;
115 
116  // -------------------------------------------------------------------------
117  // Member Functions
118  // -------------------------------------------------------------------------
119 
120  void update( std::string const& s );
121  void update( std::istream& is );
122  void update( char const* input, size_type length );
123 
124  std::string final_hex();
126 
127  static std::string from_file_hex( std::string const& filename );
128  static DigestType from_file_digest( std::string const& filename );
129 
130  static std::string from_string_hex( std::string const& input );
131  static DigestType from_string_digest( std::string const& input );
132 
133  static std::string digest_to_hex( DigestType const& digest );
134  static DigestType hex_to_digest( std::string const& hex );
135 
136  // -------------------------------------------------------------------------
137  // Internal Functions
138  // -------------------------------------------------------------------------
139 
140 private:
141 
142  void reset_();
143 
144  // MD5 block update operation. Continues an MD5 message-digest
145  // operation, processing another message block
146  void update_( unsigned char const* input, size_type length );
147 
148  // F, G, H and I are basic MD5 functions.
149  static inline uint32_t F_(uint32_t x, uint32_t y, uint32_t z);
150  static inline uint32_t G_(uint32_t x, uint32_t y, uint32_t z);
151  static inline uint32_t H_(uint32_t x, uint32_t y, uint32_t z);
152  static inline uint32_t I_(uint32_t x, uint32_t y, uint32_t z);
153 
154  // rotates x left n bits.
155  static inline uint32_t rotate_left_(uint32_t x, int n);
156 
157  // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
158  // Rotation is separate from addition to prevent recomputation.
159  static inline void FF_(
160  uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac
161  );
162  static inline void GG_(
163  uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac
164  );
165  static inline void HH_(
166  uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac
167  );
168  static inline void II_(
169  uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac
170  );
171 
172  // apply MD5 algo on a block
173  void transform_( const uint8_t block[MD5::BlockSize] );
174 
175  // decodes input (unsigned char) into output (uint32_t). Assumes len is a multiple of 4.
176  static void decode_( uint32_t output[], const uint8_t input[], size_type len );
177 
178  // encodes input (uint32_t) into output (unsigned char). Assumes len is a multiple of 4.
179  static void encode_( uint8_t output[], const uint32_t input[], size_type len );
180 
181  // -------------------------------------------------------------------------
182  // Data Members
183  // -------------------------------------------------------------------------
184 
185 private:
186 
187  uint8_t buffer_[MD5::BlockSize]; // bytes that didn't fit in last 64 byte chunk
188  uint32_t count_[2]; // 64bit counter for number of bits (lo, hi)
189  uint32_t state_[4]; // digest so far
190 
191  DigestType digest_;
192 
193 };
194 
195 } // namespace utils
196 } // namespace genesis
197 
198 // ================================================================================================
199 // Standard Hash Function
200 // ================================================================================================
201 
202 namespace std
203 {
210  template<>
211  struct hash<genesis::utils::MD5::DigestType>
212  {
214  using result_type = std::size_t;
215 
216  // We use two intermediate hashes to allow better optimization.
218  result_type hash1 = 0;
219  result_type hash2 = 0;
220  hash1 ^= ( static_cast<result_type>( s[0] ) << 0 );
221  hash1 ^= ( static_cast<result_type>( s[1] ) << 8 );
222  hash1 ^= ( static_cast<result_type>( s[2] ) << 16 );
223  hash1 ^= ( static_cast<result_type>( s[3] ) << 24 );
224  hash1 ^= ( static_cast<result_type>( s[4] ) << 32 );
225  hash1 ^= ( static_cast<result_type>( s[5] ) << 40 );
226  hash1 ^= ( static_cast<result_type>( s[6] ) << 48 );
227  hash1 ^= ( static_cast<result_type>( s[7] ) << 56 );
228  hash2 ^= ( static_cast<result_type>( s[8] ) << 0 );
229  hash2 ^= ( static_cast<result_type>( s[9] ) << 8 );
230  hash2 ^= ( static_cast<result_type>( s[10] ) << 16 );
231  hash2 ^= ( static_cast<result_type>( s[11] ) << 24 );
232  hash2 ^= ( static_cast<result_type>( s[12] ) << 32 );
233  hash2 ^= ( static_cast<result_type>( s[13] ) << 40 );
234  hash2 ^= ( static_cast<result_type>( s[14] ) << 48 );
235  hash2 ^= ( static_cast<result_type>( s[15] ) << 56 );
236  return hash1 ^ hash2;
237  }
238  };
239 }
240 
241 #endif // include guard
Calculate MD5 hashes for strings and files.
Definition: md5.hpp:82
static std::string from_file_hex(std::string const &filename)
Calculate the checksum for the content of a file, given its path.
Definition: md5.cpp:174
uint32_t size_type
Definition: md5.hpp:90
MD5()
Initialize the object for use.
Definition: md5.cpp:87
std::string final_hex()
Finish the calculation, prepare the object for next use, and return the hash.
Definition: md5.cpp:131
genesis::utils::MD5::DigestType argument_type
Definition: md5.hpp:213
void update(std::string const &s)
Add the contents of a string to the hash digest.
Definition: md5.cpp:99
static DigestType from_file_digest(std::string const &filename)
Calculate the hash digest for the content of a file, given its path.
Definition: md5.cpp:185
std::array< uint8_t, 16 > DigestType
Store an MD5 digest.
Definition: md5.hpp:101
result_type operator()(argument_type const &s) const
Definition: md5.hpp:217
static const size_t BlockSize
Definition: md5.hpp:92
DigestType final_digest()
Finish the calculation, prepare the object for next use, and return the digest.
Definition: md5.cpp:140
static DigestType hex_to_digest(std::string const &hex)
Definition: md5.cpp:225
static DigestType from_string_digest(std::string const &input)
Calculate the hash digest for the content of a string.
Definition: md5.cpp:206
double length(Tree const &tree)
Get the length of the tree, i.e., the sum of all branch lengths.
static std::string from_string_hex(std::string const &input)
Calculate the checksum for the content of a string.
Definition: md5.cpp:196
static std::string digest_to_hex(DigestType const &digest)
Definition: md5.cpp:213
MD5 & operator=(MD5 const &)=default